home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / PROGBLER / CHASM.LZH / CHASM.DOC < prev    next >
Text File  |  1986-07-10  |  166KB  |  6,535 lines

  1.  
  2.  
  3.                                           READ
  4.                                           THIS
  5.                                          BEFORE
  6.                                         PRINTING!!!!
  7.  
  8.         This document has been formatted in a special way. Virtually all dot
  9.         matrix printers have a condensed mode which prints 132 characters
  10.         across a standard 8 1/2 inch page.  When this file is printed out in
  11.         condensed mode, the resulting printed pages can be cut down to 5 1/2 X
  12.         8 1/2 inches.  The cut pages will fit nicely in the back of your
  13.         DOS manual for storage.
  14.  
  15.         Typically, you can turn on this mode by sending a special control
  16.         sequence to the printer from BASIC.  For example, you can turn on the
  17.         condensed mode of the IBM/Epson printer with the BASIC statement:
  18.         LPRINT chr$(15).  If your printer has such a condensed mode, turn it
  19.         on now, before printing the rest of this document.
  20.  
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75.                                            (tm)
  76.                                       CHASM
  77.  
  78.                                  Cheap Assembler
  79.                           for the IBM Personal Computer
  80.  
  81.                                   User's Manual
  82.                             (c) 1985 by David Whitman
  83.                                   Version 4.07
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.     David Whitman
  109.     P.O. Box 1157
  110.     North Wales, PA 19454
  111.     (215) 641-7522 (days)
  112.     (215) 234-4084 (evenings)
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.                        Table of Contents
  139.  
  140.  
  141.  
  142.     Why CHASM?..................................................1
  143.     What can CHASM do?..........................................2
  144.     What WON'T it do?...........................................3
  145.     System Requirements.........................................4
  146.     Advanced and Subset CHASM...................................5
  147.     Modifying CHASM's I/O Defaults..............................6
  148.     Syntax.....................................................11
  149.     Labels.....................................................13
  150.     Operands...................................................16
  151.     Operand Expressions........................................22
  152.     Resolution of Ambiguities..................................25
  153.     Pseudo-Operations..........................................29
  154.     Macros.....................................................38
  155.     Structures.................................................48
  156.     8087 Support...............................................52
  157.     Outside the Program Segment................................54
  158.     Running CHASM..............................................55
  159.     Error and Diagnostic Messages..............................59
  160.     Execution of Assembled Programs............................64
  161.     Notes for Those Upgrading to This Version of CHASM.........75
  162.     Miscellaneous and A Word From Our Sponsor..................78
  163.     =============================================================
  164.     Appendix A: 8088 Mnemonic List.............................83
  165.     Appendix B: 8087 Mnemonic List.............................85
  166.     Appendix C: Differences Between CHASM and TOA..............86
  167.     Appendix D: Description of Files...........................90
  168.     Appendix E: Bug Reporting Procedure........................91
  169.     Appendix F: Using CHASM on "Compatible" Systems............92
  170.     Advanced Version Order Form................................94
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.                                                                     1
  200.  
  201.     >>Why CHASM?<<
  202.  
  203.     Why go to the trouble to write an assembler, when one already
  204.     exists?  The IBM Macro Assembler is a very powerful software tool
  205.     available off the shelf.  It supports features such as macros,
  206.     multiple segments, and linking to external procedures.
  207.  
  208.     Unfortunately, the cost of all this power is complexity. The
  209.     Macro Assembler is so complicated that IBM warns beginners it is
  210.     only suitable for "experienced assembly language programmers".
  211.  
  212.     For most users, this sophistication is more of a hindrance than
  213.     an aid.  Even when writing short, simple programs, the user is
  214.     saddled with a set of confusing pseudo-ops only appropriate for
  215.     large, multi-segment programs.  Producing a fast loading
  216.     executable file requires running three separate programs (MASM,
  217.     LINK and EXE2BIN) before you can get down to testing.
  218.  
  219.     The macro assembler is totally unsuitable for use with BASIC.
  220.     Although it is *possible* to produce machine language BASIC
  221.     subroutines with the Macro Assembler, the process is incredibly
  222.     convoluted and confusing.
  223.  
  224.     To top it all off, the Macro Assembler costs an overpriced $125.
  225.  
  226.     CHASM is, I hope, a more reasonable compromise between power and
  227.     accessibility.  CHASM is simple to use and understand.  Unlike
  228.     the Macro Assembler, CHASM doesn't require a second LINK step to
  229.     produce a working program.  CHASM also produces fast loading
  230.     programs without the use of the utility EXE2BIN.
  231.  
  232.     CHASM supports several different simple mechanisms for getting
  233.     machine language routines into BASIC and Turbo Pascal, the two
  234.     most popular languages for the IBM Personal Computer.
  235.  
  236.     Finally, the suggested payment for CHASM is a modest $40.
  237.  
  238.     A Note for Beginners:
  239.  
  240.     Before going on, you might find it useful to print and read the
  241.     file PRIMER.DOC, included on your CHASM disk.  PRIMER is a gentle
  242.     introduction to assembly language, which will teach you some of
  243.     the vocabulary and key concepts you will need to start out with.
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.                                                                     2
  266.  
  267.     >>What can CHASM do?<<
  268.  
  269.     CHASM is a tool for translating assembly language into the native
  270.     machine language of the 8088 microprocessor.  Using CHASM, you
  271.     can write down easy to remember "mnemonics" which are then
  272.     converted into the relatively incomprehensible series of ones and
  273.     zeros that your PC prefers to work with.
  274.  
  275.     In addition to simple mnemonic translation (such as provided by
  276.     the mini-assembler in DEBUG), CHASM provides a great many
  277.     "convenience" features which make writing machine language much
  278.     easier.
  279.  
  280.     CHASM allows you to define labels for branching, rather than
  281.     requiring you to figure out offsets or addresses to jump to.
  282.     CHASM also lets you give symbolic names to any constants or
  283.     memory locations you use, to make your program easier to
  284.     understand.
  285.  
  286.     You can instruct CHASM to make your file "BLOADable" so that
  287.     BASIC can load it as a subroutine.   A utility is also provided
  288.     to convert machine language into BASIC "DATA" statements, so that
  289.     BASIC can "POKE" routines into memory.  Similarly, for Turbo
  290.     Pascal CHASM can produce external procedures and functions, or a
  291.     file of Turbo "INLINE" statements.
  292.  
  293.     CHASM has intelligent error and diagnostic messages which guide
  294.     you in correcting mistakes and ambiguities in your program.  A
  295.     nicely formatted listing is produced during assembly, to help
  296.     during debugging.
  297.  
  298.     In general, CHASM is designed to eliminate much of the confusion
  299.     and dirty work involved in writing machine language for the IBM
  300.     PC.
  301.  
  302.     Using CHASM, you can produce:
  303.  
  304.        1. Lightning fast "stand-alone" programs.
  305.  
  306.        2. Machine language subroutines for BASIC programs, both
  307.           interpreted and compiled.
  308.  
  309.        3. Machine language procedures and functions for Turbo Pascal.
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.                                                                     3
  332.  
  333.     >>What WON'T it do?<<
  334.  
  335.     In the interest of simplicity, CHASM has the following
  336.     restrictions:
  337.  
  338.     1. Multiple segment definitions are not allowed. CHASM assumes
  339.        that your entire program fits in one segment, that the cs, ds,
  340.        and es registers all point to this same segment, and that the
  341.        ss register points to a valid stack area.  An equivalent
  342.        statement is that CHASM produces COM files, not EXE files.
  343.  
  344.     2. Linking to Microsoft languages is not supported.  You can't
  345.        use CHASM to produce object modules for use with IBM/Microsoft
  346.        Pascal or FORTRAN.
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.                                                                     4
  398.  
  399.     >>System Requirements<<
  400.  
  401.     Minimum system requirements to use CHASM are:
  402.  
  403.          IBM PC or true compatible (must emulate IBM BIOS)
  404.          128K of memory            (192K for IBM PCjr)
  405.          1 disk drive
  406.          80 column display
  407.          DOS 2.0 or later.
  408.  
  409.     Note the DOS 2 requirement.  To provide *true* DOS 2 support, it
  410.     was necessary to give up DOS 1 compatibility.  If you're still
  411.     using DOS 1, you'll need to upgrade to DOS 2.0 or later to use
  412.     CHASM.
  413.  
  414.     Adding more memory will allow you to assemble larger programs.
  415.     CHASM can take advantage of all available memory, up to a
  416.     megabyte.
  417.  
  418.     CHASM will run faster if your source files and object files are
  419.     on a hard disk or RAM disk.
  420.  
  421.     If you have a non-IBM computer, please read about the /VIDEO
  422.     switch in "Modifying CHASM's I/O Defaults" and also the appendix
  423.     titled "Using CHASM on Compatible Systems"
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448.  
  449.  
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.                                                                     5
  464.  
  465.     >>Advanced and Subset CHASM<<
  466.  
  467.     CHASM is available in two flavors, Advanced and Subset.
  468.     The two versions vary in their capabilities and method of
  469.     distribution.
  470.  
  471.     The subset version is the budget release.  It may be freely
  472.     copied by individuals as "user-supported" software, and is
  473.     available from user groups and bulletin boards across the
  474.     country.  Every time the subset runs, it prints a banner page
  475.     suggesting a payment of $40 to the author.  As its name
  476.     suggests, Subset CHASM does not support all the features of
  477.     Advanced CHASM.
  478.  
  479.     Advanced CHASM is the deluxe release.  It runs twice as fast, and
  480.     has a number of features not supported by the subset:
  481.  
  482.           macros
  483.           conditional assembly
  484.           8087 support
  485.           include files
  486.           structures
  487.  
  488.     Advanced CHASM is only available directly from Whitman Software.
  489.     Users who make the suggested $40 payment receive an upgrade to
  490.     Advanced CHASM.  Details, and an order blank are given at the
  491.     end of this document.
  492.  
  493.     Throughout this document, features supported only by the
  494.     advanced version will be marked as follows:
  495.  
  496.       ==>Advanced version only.
  497.  
  498.     Attempts to use these features in the subset version will
  499.     generally result in error messages, with the advanced feature
  500.     otherwise being ignored; however, unpredictable behavior could
  501.     result in some instances.
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.                                                                     6
  530.  
  531.     >>MODIFYING CHASM'S I/O DEFAULTS<<
  532.  
  533.     CHASM supports the use of a configuration file, which can be used
  534.     to override some of CHASM's I/O defaults.  If you are willing to
  535.     accept CHASM's defaults, you may skip this section - on most
  536.     systems, CHASM will work perfectly well without the file
  537.     described below.
  538.  
  539.     The configuration process involves supplying a text file named
  540.     CHASM.CFG on your default drive.  You can create this file with
  541.     any text editor or word processor.
  542.  
  543.     You have some freedom in where you put the configuration file.
  544.     If CHASM.CFG is not found in the current directory, CHASM will
  545.     also try the following paths:
  546.  
  547.           \CHASM\CHASM.CFG
  548.           \CHASM.CFG
  549.  
  550.     The file should contain a series of text "switches" of the
  551.     following form:
  552.  
  553.     /SWITCH, xx [, yy, zz,...]
  554.  
  555.     Where "/SWITCH" is a reserved word, listed below, and xx, yy, zz
  556.     are numbers.  The brackets around yy and zz indicate that these
  557.     numbers are optional - don't put brackets in CHASM.CFG.
  558.  
  559.     Each switch should start a new line, and the switch and each of
  560.     the numbers should separated by one or more blanks or commas.
  561.  
  562.     The following switches are implemented:
  563.  
  564.     /VIDEO      Video access method.  With this switch, you can
  565.                 control the method CHASM uses to write data on your
  566.                 video screen.  Three settings are currently
  567.                 supported:
  568.  
  569.                 /VIDEO 0  Direct write to screen memory.
  570.  
  571.                 /VIDEO 1  Direct write to screen memory, but only
  572.                           during the horizontal retrace interval.
  573.  
  574.                 /VIDEO 2  Write using BIOS calls.
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.                                                                     7
  596.  
  597.     /VIDEO      (continued) In general, the lower a number you
  598.                 specify for /VIDEO, the faster CHASM will run.
  599.  
  600.                 /VIDEO 0 is the fastest mode, and is intended for use
  601.                 with either the IBM monochrome display adapter or the
  602.                 EGA adapter.  You can use /VIDEO 0 with the CGA
  603.                 adapter, but some annoying "snow" and flicker may
  604.                 result.
  605.  
  606.                 /VIDEO 1 is intended for use with the CGA adapter.
  607.                 It is almost as fast as /VIDEO 0, and the snow is
  608.                 eliminated.  /VIDEO 1 is CHASM's default mode.
  609.  
  610.                 /VIDEO 2 is intended for non-IBM systems that emulate
  611.                 the IBM BIOS, but have significantly different screen
  612.                 hardware.  If you have trouble running CHASM on a
  613.                 "compatible" system, try setting /VIDEO 2.  Use of
  614.                 /VIDEO 2 will slow CHASM down significantly.
  615.  
  616.     /FG         Foreground color.  Users with color monitors may
  617.                 select a foreground color from the following list:
  618.  
  619.                 0    Black               8    Gray
  620.                 1    Blue                9    Light Blue
  621.                 2    Green              10    Light Green
  622.                 3    Cyan               11    Light Cyan
  623.                 4    Red                12    Light Red
  624.                 5    Magenta            13    Light Magenta
  625.                 6    Brown              14    Yellow
  626.                 7    White              15    High Intensity White
  627.  
  628.                 Example: (Magenta)
  629.  
  630.                 /FG 5
  631.  
  632.     /BG         Background color.  Selections 0-7 above are
  633.                 available. Example: (Cyan)
  634.  
  635.                 /BG, 3
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.                                                                     8
  662.  
  663.     /132        Printer 132 column mode.  The numbers following this
  664.                 switch are the ASCII codes for the characters which
  665.                 cause your printer to go into condensed mode.  You
  666.                 may specify as many characters as you like.  If you
  667.                 don't provide this switch, CHASM will truncate source
  668.                 lines in listings to avoid going over 80 columns. You
  669.                 can also include characters to activate any special
  670.                 features of your printer you want CHASM to use during
  671.                 printing.  Example: (for IBM printer)
  672.  
  673.                 /132, 15
  674.  
  675.     /80         Printer 80 column mode.  Similar to /132, but the
  676.                 numbers represent the characters to return your
  677.                 printer to normal.  Include the codes for any
  678.                 characters you want CHASM to send to your printer
  679.                 before returning you to DOS.  The following example
  680.                 turns off condensed mode and causes a Form Feed on
  681.                 the IBM printer:
  682.  
  683.                 /80, 18, 12
  684.  
  685.     /FF         Formfeed.  A value of zero tells CHASM that your
  686.                 printer doesn't recognize ASCII 12 as a formfeed
  687.                 command.  Any other value, and CHASM assumes that
  688.                 formfeeds will be recognized.  The default is no
  689.                 formfeed character.
  690.  
  691.                 If /FF is off, CHASM will simulate formfeeds with a
  692.                 series of linefeeds.  However, most printers respond
  693.                 quicker to a formfeed than to multiple line feeds, so
  694.                 set /FF on if possible.  Example: (on)
  695.  
  696.                 /FF 1
  697.  
  698.     /PAGELEN    CHASM assumes that there are 66 lines to each printed
  699.                 page.  If you use different sized paper, enter the
  700.                 number of lines per page after this switch.
  701.                 Example: (European standard)
  702.  
  703.                 /PAGELEN 72
  704.  
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711.  
  712.  
  713.  
  714.  
  715.  
  716.  
  717.  
  718.  
  719.  
  720.  
  721.  
  722.  
  723.  
  724.  
  725.  
  726.  
  727.                                                                     9
  728.  
  729.     /LINES      By default, CHASM will print 58 lines on each printed
  730.                 page, then skip over the perforation to the next
  731.                 page.  You can change this number to suit your paper
  732.                 and personal taste.  Example:
  733.  
  734.                 /LINES 50
  735.  
  736.     /BEEP       Enables/Disables audible warning when errors are
  737.                 discovered in your source program.  A value of zero
  738.                 turns off beeping, anything else turns it on. The
  739.                 default is on.  Example: (off)
  740.  
  741.                 /BEEP 0
  742.  
  743.      /DWIDTH    When listing to a disk file, CHASM normally truncates
  744.                 listing lines to 80 columns to prevent wrap-around
  745.                 when viewing the file.  In some instances, such as
  746.                 disk-based print spooling with DOS's PRINT utility,
  747.                 you may wish to override this truncation.  You can
  748.                 enter a new truncation limit after this switch. 
  749.                 Example: (128 column lines)
  750.  
  751.                 /DWIDTH 128
  752.  
  753.      /DPAGE     For easier scanning, listings sent to disk files do
  754.                 not normally contain page breaks.   If you want to
  755.                 produce printable listing files, you can turn on page
  756.                 breaks by setting /DPAGE to any value other than
  757.                 zero.  Example: (page breaks on)
  758.  
  759.                 /DPAGE 1
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.                                                                    10
  794.  
  795.       /PATH     Path Strategy.  Affects the way CHASM constructs the
  796.                 default file names for list and object files.  If
  797.                 /PATH is set to 0 (the default), any drive or path
  798.                 specified on the source file name will be included in
  799.                 the default file names.  If /PATH is set to anything
  800.                 else, path and drive info are removed, thus putting
  801.                 the default list and object files in the current
  802.                 directory of the logged drive.  The following table
  803.                 shows how this works:
  804.  
  805.                 /PATH | Source filename   | Default object file
  806.                 ------|-------------------|-------------------------
  807.                    0  | a:\chasm\test.asm |   a:\chasm\test.com
  808.                    1  | a:\chasm\test.asm |   test.com
  809.  
  810.                 /PATH only affects how the default file names are
  811.                 constructed - CHASM won't edit filenames that you
  812.                 explicitly type in.
  813.  
  814.      /TIMER     Enables/Disables reporting of total assembly time. A
  815.                 value of 0 turns off timing, anything else turns it
  816.                 on.  The default is off.  This switch is used
  817.                 internally at Whitman Software to benchmark new
  818.                 versions of CHASM.
  819.  
  820.     A sample CHASM.CFG file, suitable for use with the IBM dot matrix
  821.     printer, is included on your CHASM distribution disk.
  822.  
  823.  
  824.  
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.  
  857.  
  858.  
  859.                                                                    11
  860.  
  861.     >>Syntax<<
  862.  
  863.     CHASM accepts a standard DOS text file for input.  In this
  864.     context, "standard DOS text file" means:
  865.  
  866.         1. Lines are terminated with a CR/LF pair.
  867.  
  868.         2. The end of the file is marked with an EOF marker (cntl-Z).
  869.  
  870.     Virtually every word processor or editor produces files which
  871.     meet these criteria.  Some word processors have to be in a
  872.     special mode to produce standard DOS files.  (For example, in
  873.     WordStar, you have to be in "non-document" mode.) The user's
  874.     manual for your editor should inform you if any special mode
  875.     needs to be activated.
  876.  
  877.     Some users have reported problems with the user-supported word
  878.     processor PC-Write.  Under certain circumstances, older
  879.     versions of PC-Write can produce lines ending with just a LF
  880.     (violation of rule 1) or files which aren't terminated with an
  881.     EOF marker (violation of rule 2).  If you use PC-Write, make sure
  882.     you have the latest version.
  883.  
  884.     Lines may be any combination of upper and lower case characters.
  885.     CHASM does not distinguish between the two cases: everything
  886.     except single quoted strings are automatically converted to upper
  887.     case during the parsing process.  Thus, BUFFER, Buffer, buffer,
  888.     and bUFFer all refer to the same symbol.
  889.  
  890.     The characters  blank ( ), comma (,), single quote (')
  891.     semi-colon (;) and TAB are reserved, and have special meaning to
  892.     CHASM (see below).  The characters + - * / ) ( are reserved for
  893.     use as operators in expressions.
  894.  
  895.     Each line must be no more than 80 characters long and have the
  896.     following format:
  897.  
  898.        Label Operation Operand(s) ;comment
  899.  
  900.     The different fields of an input line are separated by the
  901.     delimiters blank ( ), comma (,) or TAB.  Any number of any
  902.     delimiter may be used to separate fields.
  903.  
  904.  
  905.  
  906.  
  907.  
  908.  
  909.  
  910.  
  911.  
  912.  
  913.  
  914.  
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.  
  924.  
  925.                                                                    12
  926.  
  927.     Explanation of Fields:
  928.  
  929.     Label: A label is a string of characters, beginning in column 1.
  930.        Depending on the operation field, the label might represent a
  931.        program location for branching, a memory location, or a
  932.        numeric constant (see the section titled "Labels" for more on
  933.        this topic). No reserved characters can appear within the
  934.        label, and to ensure that CHASM can distinguish between labels
  935.        and numeric constants, the first character of a label must
  936.        *not* be a numeric (i.e. 0-9). Anything beginning in column 1,
  937.        except a comment, is considered a label.
  938.  
  939.     Operation: Either a pseudo-op (see the section with the same
  940.        name) or an instruction mnemonic as defined in "The 8086
  941.        Book" by Rector and Alexy.  A list of acceptable mnemonics is
  942.        given in Appendix A.
  943.  
  944.        Note 1: Except as modified below,"The 8086 Book" is the
  945.           definitive reference for use with CHASM.
  946.  
  947.        Note 2: There are several ways to resolve some ambiguities in
  948.           8086 assembly language.  Please read page 3-285 of The 8086
  949.           Book, and "Resolution of Ambiguities" in this document.
  950.  
  951.     Operand(s): A list of one or more operands, as defined in
  952.        the section titled "Operands", separated by delimiters.
  953.  
  954.     Comment: Any string of characters, beginning with a semicolon
  955.        (;). Anything to the right of a semicolon will be ignored by
  956.        CHASM.
  957.  
  958.     Note that except for the case of an operation which requires
  959.     operands, or the EQU pseudo-op which requires a label, all of the
  960.     fields are optional.  The fields MUST appear in the order shown.
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.                                                                    13
  992.  
  993.     >>Labels<<
  994.  
  995.     The symbol in the label field of an input line can be interpreted
  996.     in four different ways by CHASM:
  997.  
  998.       1. A program location which may be branched to.
  999.  
  1000.       2. A memory location for data storage.
  1001.  
  1002.       3. An equated symbol, which takes the place of a numeric
  1003.          constant.
  1004.  
  1005.       4. A macro name, which takes the place of a series of
  1006.          frequently used source code lines.
  1007.  
  1008.     The default interpretation of a symbol is a program location for
  1009.     branching.  This default is modified by the presence of one of
  1010.     the following pseudo-ops in the instruction field:
  1011.  
  1012.     DB, DM, DS, or DW:
  1013.  
  1014.           Normal:  The symbol is a memory location.
  1015.  
  1016.           In a Structure: The symbol is a numeric constant.
  1017.  
  1018.     EQU:
  1019.  
  1020.           Normal:  The symbol is a numeric constant.
  1021.  
  1022.           Memory Option:  The symbol is a memory location.
  1023.  
  1024.     MACRO: 
  1025.          The symbol is a macro name.
  1026.  
  1027.     A given symbol may have only ONE of the above interpretations!
  1028.     Attempts to branch into a memory location or an equated symbol
  1029.     will result in error messages.  Similarly, CHASM will not allow
  1030.     you to treat program code as a data area.  Examples:
  1031.  
  1032.     TEXT DB  'Hit any key when ready'  ;memory location
  1033.          MOV  AL,TEXT                  ;ok
  1034.          JMP  TEXT                     ;wrong!
  1035.     LOOP MOV  AX,CX                    ;program location
  1036.          JMP  LOOP                     ;ok
  1037.          MOV  AX, LOOP                 ;wrong!
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.                                                                    14
  1058.  
  1059.     If for some arcane reason you *need* to branch into a data area,
  1060.     you can fool CHASM by placing a label on an otherwise blank line,
  1061.     immediately before the data area.  Example:
  1062.  
  1063.           JNZ NPU
  1064.           RET
  1065.     NPU                                ;dummy label for jump
  1066.           DB  D8H, 00H                 ;an 8087 instruction
  1067.  
  1068.     If you have a masochistic urge to crash your system by writing
  1069.     self-modifying code, there are at least two ways you can defeat
  1070.     CHASM's injunction against using program code as a data area.
  1071.  
  1072.     The first way is to use DS to declare zero bytes of storage
  1073.     immediately before the code you want to access.  A label on the
  1074.     null DS will have the same offset as the immediately following
  1075.     code.  Example:
  1076.  
  1077.            MOV   JUNK1, 9090         ;change endless loop to NOP
  1078.     JUNK1  DS    0
  1079.     JUNK   JMP  JUNK
  1080.  
  1081.     A sneakier approach is to load the OFFSET of a program
  1082.     location into a register, then use the register for indirect
  1083.     addressing. Using the optional displacement field, you can even
  1084.     address the middle of an instruction.  Examples:
  1085.  
  1086.            MOV   BX, OFFSET(CALL)
  1087.            MOVB  1[BX], 00H          ;change interrupt number in code
  1088.     CALL   INT   0
  1089.  
  1090.     In general, I cannot recommend trying to get around CHASM's type
  1091.     restrictions.  If you find yourself in a situation where it
  1092.     seems necessary to fool CHASM, there's probably a safer, more
  1093.     direct way to legally program what you're trying to accomplish.
  1094.  
  1095.     Labels can be up to 80 characters long, but only the first 15
  1096.     characters are significant.  For example, CHASM considers the
  1097.     following labels identical:
  1098.  
  1099.        VERYLONGLABELOVER15CHARACTERS
  1100.        VERYLONGLABELOVER
  1101.  
  1102.  
  1103.  
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.                                                                    15
  1124.  
  1125.     To avoid ambiguity, a given string can legally appear in the
  1126.     label field of only ONE statement.  If the same string appears on
  1127.     more than one instruction, all instances after the first will
  1128.     receive an error message.  Remember that labels are only
  1129.     significant to 15 characters, and if the first 15 characters are
  1130.     identical, an error will occur.
  1131.  
  1132.     TWO   EQU  '2'      ;first use is ok
  1133.     TWO   PROC FAR      ;wrong! symbol already defined
  1134.  
  1135.     CHASM has a number of reserved strings which are "predefined" in
  1136.     the symbol table, and will generate an error message if used as
  1137.     labels.  All the register names are reserved, as are the indirect
  1138.     address mode combinations.  The only other reserved strings are
  1139.     the words "NEAR" and "FAR", and the symbol "$". Examples:
  1140.  
  1141.     AX   MOV  AX, DX      ;wrong! (register name)
  1142.     [DI] ADD  AX, BX      ;wrong! (indirect address)
  1143.     FAR  CALL GETINPUT    ;wrong! (reserved word)
  1144.     $    SUB  AX, DX      ;wrong! (reserved word)
  1145.  
  1146.  
  1147.  
  1148.  
  1149.  
  1150.  
  1151.  
  1152.  
  1153.  
  1154.  
  1155.  
  1156.  
  1157.  
  1158.  
  1159.  
  1160.  
  1161.  
  1162.  
  1163.  
  1164.  
  1165.  
  1166.  
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.                                                                    16
  1190.  
  1191.     >>Operands<<
  1192.  
  1193.     The following operand types are allowed.
  1194.  
  1195.     1. Immediate data: A number, stored as part of the program's
  1196.        object code.  Immediate data are classified as either byte,
  1197.        expressible as an 8 bit binary integer; or word, expressible
  1198.        as a 16 bit binary integer.  If context requires it, CHASM
  1199.        will left-pad byte values with zeroes to convert them to word
  1200.        values.  Attempts to use a word value where only a byte will
  1201.        fit will cause an error message to be printed.
  1202.  
  1203.        Immediate data may be represented in 9 ways:
  1204.  
  1205.           A. An optionally signed decimal number in the range -32768
  1206.              to 32767.  Examples:
  1207.  
  1208.              MOV AL, 21
  1209.              MOV BX, -6300
  1210.  
  1211.           B. A series of up to 4 hex digits, followed by the letter
  1212.              H.  The first digit must be non-alphabetic, i.e. in the
  1213.              range 0-9, to allow CHASM to distinguish between numbers
  1214.              and symbols. If necessary, a leading zero, which does
  1215.              not count in the four allowed digits, may be added to
  1216.              fulfill the non-alphabetic condition.
  1217.  
  1218.              If the RADIX pseudo-op has been used to change the
  1219.              default number base to 16, the final H can optionally be
  1220.              omitted.  Examples:
  1221.  
  1222.              ADD   CX, 0B123H   ;leading zero required
  1223.              RADIX 16           ;change default number base
  1224.              ADD   DL, 12       ;same as 12H
  1225.  
  1226.          C.  A series of up to 16 binary digits, followed by the
  1227.              letter B.  Examples:
  1228.  
  1229.              MASK   EQU   00000111B
  1230.                     MOV   AL, 10000000B
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.                                                                    17
  1256.  
  1257.           D. A symbol representing types A, B or C above, defined
  1258.              using the EQU pseudo-op.  Examples:
  1259.  
  1260.              MASK EQU 10H
  1261.              MAX  EQU 1000
  1262.                   AND  CL,MASK
  1263.                   SUB  AX,MAX
  1264.  
  1265.           E. The offset of a label or storage location returned by
  1266.              the OFFSET operator.  OFFSET always returns a word
  1267.              value. OFFSET is used to get the address of a named
  1268.              memory location, rather than its contents.  Example:
  1269.  
  1270.                     MOV DI,OFFSET(BUFFER)
  1271.              BUFFER DS  0FFH
  1272.  
  1273.           F. The ASCII value of a printable character, represented by
  1274.              the character enclosed in single quotes (').  Thus, the
  1275.              following lines will generate the same object code:
  1276.  
  1277.                 MOV AL,41H  ;ascii code for 'A'
  1278.                 MOV AL,'A'
  1279.  
  1280.           G. When producing Turbo Pascal INLINE code, the function
  1281.              TURBO(x) assembles as 16 bit immediate data.
  1282.  
  1283.           H. ==>Advanced version only:
  1284.              Labels within structures become immediate operands whose
  1285.              values equal their offset within the structure.  See the
  1286.              section titled "Structures" for more detail and
  1287.              examples.
  1288.  
  1289.           I. ==>Advanced version only:
  1290.              The length of a structure, returned either by the LENGTH
  1291.              operator, or simply the structure's name.  See the
  1292.              section titled "Structures" for more detail and
  1293.              examples.
  1294.  
  1295.           J. An expression that evaluates out to type Immediate.
  1296.              Examples:
  1297.  
  1298.                     MOV AX, (3+2)*5 
  1299.                     MOV DX, MEMLOC1-MEMLOC2
  1300.  
  1301.              See the "Operand Expressions" section for more details.
  1302.  
  1303.  
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.  
  1319.  
  1320.  
  1321.                                                                    18
  1322.  
  1323.     2. Register Operands
  1324.  
  1325.        A. An 8 bit 8088 register from the following list:
  1326.           AH    AL
  1327.           BH    BL
  1328.           CH    CL
  1329.           DH    DL
  1330.  
  1331.        B. A 16 bit 8088 register from the following list:
  1332.  
  1333.           AX   BX   CX   DX   SP   BP   SI   DI
  1334.  
  1335.        C. An 8088 segment register from the following list:
  1336.  
  1337.           CS   SS   DS   ES
  1338.  
  1339.        D. An 8087 stack register from the following list:
  1340.  
  1341.           ST ST(1) ST(2) ST(3) ST(4) ST(5) ST(6) ST(7)
  1342.  
  1343.           Note: ST can also be referenced as ST(0).
  1344.  
  1345.     3. Memory Operands: The contents of a memory location addressed
  1346.        by one of the following methods.  Note that none of the memory
  1347.        addressing options specifies the *size* of the operand.  8088
  1348.        instructions have word or byte sized operands, and 8087
  1349.        instructions can have word, short, long or temporary real
  1350.        operands.  See the section titled "Resolution of Ambiguities"
  1351.        for more on this topic.
  1352.  
  1353.        All memory operands can optionally be preceded with a segment
  1354.        override to specify the segment register to be used in
  1355.        accessing memory.  The override takes the form of a segment
  1356.        register, followed by a colon, followed by the memory operand.
  1357.        No intervening delimiters are allowed.  Examples:
  1358.  
  1359.             MOV AX, ES:[80H]   ;80H into the extra segment
  1360.             MOV CS:[DI], SI     ;indirect with DI in the code segment
  1361.  
  1362.        Segment overrides are also discussed in the section titled
  1363.        "Resolution of Ambiguities".
  1364.  
  1365.  
  1366.  
  1367.  
  1368.  
  1369.  
  1370.  
  1371.  
  1372.  
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.  
  1379.  
  1380.  
  1381.  
  1382.  
  1383.  
  1384.  
  1385.  
  1386.  
  1387.                                                                    19
  1388.  
  1389.        A. Direct Memory Address.
  1390.  
  1391.           1. A number or other immediate operand, enclosed in
  1392.              brackets, indicating an offset into the data segment.
  1393.              Example:
  1394.  
  1395.              BUFFER EQU 5A5AH
  1396.                     MOV BH, [BUFFER]
  1397.                     MOV [80H], DI
  1398.                     MOV AX, CS:[TURBO(I)]
  1399.  
  1400.           2. A symbol, defined to be a variable (i.e. a named memory
  1401.              location) using the EQU pseudo-op.  Example:
  1402.  
  1403.              FCB EQU [80H]
  1404.                  MOV DI,FCB
  1405.  
  1406.           3. A symbol, defined to be a variable by its use on a
  1407.              storage defining pseudo-op.  Examples:
  1408.  
  1409.                   MOV AX,FLAG
  1410.                   MOV DATE,BX
  1411.              FLAG DS 1
  1412.              DATE DB 31
  1413.  
  1414.           4. The special symbol '$'.  $ returns an address of value
  1415.              equal to the current setting of CHASM's location
  1416.              counter.  This address can be used as either a memory
  1417.              location or a program location for branching.  Used by
  1418.              itself, $ has little utility, but it is a very powerful
  1419.              tool when used in expressions.  Example:
  1420.  
  1421.                   MOV AX, $+4    ;get the byte after this instruction
  1422.  
  1423.           5. ===> Advanced version only:
  1424.              An expression that evaluates out to type address.
  1425.              Example:
  1426.  
  1427.                     MOV AX, buffer+3
  1428.              BUFFER DS 20
  1429.  
  1430.              See the "Operand Expressions" section for more details.
  1431.  
  1432.  
  1433.  
  1434.  
  1435.  
  1436.  
  1437.  
  1438.  
  1439.  
  1440.  
  1441.  
  1442.  
  1443.  
  1444.  
  1445.  
  1446.  
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.                                                                    20
  1454.  
  1455.        B. Indirect Memory Address:  The address of the operand is the
  1456.           sum of the contents of the indicated register(s) and a
  1457.           displacement.  The register, or sum of registers, are
  1458.           enclosed in square brackets: []
  1459.  
  1460.           The displacement is optional, and takes the form of an
  1461.           immediate operand, placed without intervening delimiters to
  1462.           the left of the first bracket.
  1463.  
  1464.           Immediate data written as decimal numbers, with values
  1465.           between 127 and -128 generate a signed 8 bit offset.
  1466.           Values outside this range, or those expressed in some
  1467.           other manner generate 16 bit offsets.
  1468.  
  1469.           The following indirect modes are provided:
  1470.  
  1471.           1. Indirect through a base register (BX or BP).  Examples:
  1472.  
  1473.              ENTRYLENGTH EQU 6
  1474.                          MOV AX, ENTRYLENGTH[BP]
  1475.                          MOV DL, -2[BX]
  1476.                          MOV CX, TURBO(COUNT)[BP]
  1477.                          MOV 9A9AH[BX], AX
  1478.  
  1479.           2. Indirect through an index register (DI or SI).
  1480.              Examples:
  1481.  
  1482.              MOV [DI], CX
  1483.              MOV CX, -5[SI]
  1484.  
  1485.           3. Indirect through the sum of one base register and one
  1486.              index register.  Examples:
  1487.  
  1488.              MOV [BP+DI], SP      ;note that no spaces are
  1489.              MOV BX, 10H[BX+SI]   ;allowed within the
  1490.              MOV CL, [BP+SI]      ;brackets.
  1491.              MOV DH, -2[BX+DI]
  1492.  
  1493.  
  1494.  
  1495.  
  1496.  
  1497.  
  1498.  
  1499.  
  1500.  
  1501.  
  1502.  
  1503.  
  1504.  
  1505.  
  1506.  
  1507.  
  1508.  
  1509.  
  1510.  
  1511.  
  1512.  
  1513.  
  1514.  
  1515.  
  1516.  
  1517.  
  1518.  
  1519.                                                                    21
  1520.  
  1521.     4. Labels
  1522.  
  1523.        A label on most instructions may be used as an operand for
  1524.        call and jump instructions.  See the section titled "Labels"
  1525.        for more information.  Examples:
  1526.  
  1527.        START    PROC NEAR
  1528.                 CALL GETINPUT
  1529.                 JMPS START
  1530.                 ENDP
  1531.        GETINPUT PROC NEAR
  1532.  
  1533.     5. Strings
  1534.  
  1535.        A string is any sequence of characters (including delimiters)
  1536.        surrounded by single quotes (').  If you want to use the
  1537.        single quote character inside a string, put two of them
  1538.        in a row for each one you want in the string. Example:
  1539.  
  1540.        DB 'This is a ''string'' with embedded quotes'
  1541.  
  1542.  
  1543.  
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.  
  1550.  
  1551.  
  1552.  
  1553.  
  1554.  
  1555.  
  1556.  
  1557.  
  1558.  
  1559.  
  1560.  
  1561.  
  1562.  
  1563.  
  1564.  
  1565.  
  1566.  
  1567.  
  1568.  
  1569.  
  1570.  
  1571.  
  1572.  
  1573.  
  1574.  
  1575.  
  1576.  
  1577.  
  1578.  
  1579.  
  1580.  
  1581.  
  1582.  
  1583.  
  1584.  
  1585.                                                                    22
  1586.  
  1587.     >>Operand Expressions<<
  1588.  
  1589.     CHASM can perform arithmetic calculations at assemble time, to
  1590.     help you generate memory addresses and immediate data constants.
  1591.  
  1592.     The following operand types can participate in operand
  1593.     expressions: 
  1594.  
  1595.          immediate data
  1596.          program locations
  1597.          data storage locations
  1598.  
  1599.     Actually, for the purpose of expression evaluation, CHASM treats
  1600.     both program locations and data storage locations identically.
  1601.     Thus, really only two types of operands are allowed in
  1602.     expressions: immediate and address.
  1603.  
  1604.     Symbols standing for immediate operands must have been defined
  1605.     prior to use in an expression, or you may get Phase Errors (see
  1606.     the error message section for a discussion on this topic).  You
  1607.     should put all your EQU and STRUC pseudo-ops at the beginning of
  1608.     your program, before any machine instructions.
  1609.  
  1610.     The following arithmetic operators are available:
  1611.  
  1612.          +  addition
  1613.          -  subtraction
  1614.          *  multiplication
  1615.          /  integer division
  1616.  
  1617.     Note that / performs *integer* division.  5/2 evaluates to 2.
  1618.  
  1619.     The normal rules of precedence apply.  To force evaluation
  1620.     contrary to normal precedence, you can use parenthesis: ().
  1621.  
  1622.          MOV AX  2+5*3   ;means mov ax, 17 because * outranks +
  1623.          MOV AX, (2+5)*3 ;means mov ax, 21
  1624.  
  1625.     No delimiters can appear within an expression.  If you separate
  1626.     the parts of an expression with delimiters, CHASM will try to
  1627.     interpret each part as a separate operand.
  1628.  
  1629.          MOV [BX], BUFFER + 3    ;WRONG!!
  1630.          MOV [BX], BUFFER+3      ;ok
  1631.  
  1632.  
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.  
  1639.  
  1640.  
  1641.  
  1642.  
  1643.  
  1644.  
  1645.  
  1646.  
  1647.  
  1648.  
  1649.  
  1650.  
  1651.                                                                    23
  1652.  
  1653.     The type of an operand expression is determined by the individual
  1654.     operand types that are combined within it.  In evaluating each
  1655.     operation in an expression, the result type follows this rule:
  1656.  
  1657.          If the two operand types are the same, the result type is
  1658.          IMMEDIATE.
  1659.  
  1660.          If the two operand types are different, the result type is
  1661.          an ADDRESS.
  1662.  
  1663.     In expressions, both program locations and data storage locations
  1664.     are considered identical.  An expression which evaluates to type
  1665.     address can be used in either a MOV or a JMP.
  1666.  
  1667.     The result type of a complicated expression is determined by
  1668.     replacing individual binary operations with their result, and
  1669.     evaluating the (simpler) expression thus formed, following the
  1670.     above rules.
  1671.  
  1672.     Here's a program fragment with some expressions, and a discussion
  1673.     of their types and significance:
  1674.  
  1675.     EXPSAMPLE PROC  NEAR
  1676.               MOV   AX, 3+5         ;immediate, calculated value
  1677.               MOV   DX, STRING-END  ;immediate, length of string
  1678.               MOV   STRING+5, 'A'   ;address, fifth byte of string
  1679.               JMP   EXPSAMPLE+100H  ;address, used as program loc.
  1680.               JMP   STRING+100H     ;valid address syntax, but silly
  1681.     STRING    DB    'MESSaGE'       ;data area
  1682.     END                             ;marks position of end of string
  1683.  
  1684.  
  1685.     The special symbol '$' returns the current value of CHASM's
  1686.     location counter for use in expressions.  $ is of type address.
  1687.     Thus, $-1 is the address of the byte immediately prior to the
  1688.     instruction currently being assembled.
  1689.  
  1690.  
  1691.  
  1692.  
  1693.  
  1694.  
  1695.  
  1696.  
  1697.  
  1698.  
  1699.  
  1700.  
  1701.  
  1702.  
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.  
  1713.  
  1714.  
  1715.  
  1716.  
  1717.                                                                    24
  1718.  
  1719.     The rules for typing expressions were set up to produce the
  1720.     "most useful" result type, taking a guess as to why one would
  1721.     want to do a given calculation.  If the type isn't what you have
  1722.     in mind, you can coerce CHASM using square brackets or the
  1723.     OFFSET function:
  1724.  
  1725.           MOV AX, 3+5              ;immediate
  1726.           MOV AX, [3+5]            ;coerced to address
  1727.           MOV DX, $+4              ;address
  1728.           MOV DX, OFFSET($+4)      ;coerced to immediate
  1729.  
  1730.     Under certain circumstances, CHASM can get confused when you use
  1731.     OFFSET or LENGTH functions in expressions.  The problem occurs if
  1732.     the expression starts with a function, and ends with a close
  1733.     parenthesis:
  1734.  
  1735.           MOV AX, OFFSET(BUFFER)*(3+2)    ;will be misinterpreted
  1736.  
  1737.     CHASM will try to interpret this as the offset of "BUFFER)*(3+2",
  1738.     and you'll get the error message "Illegal or undefined argument
  1739.     for OFFSET".  The solution is to enclose the whole works in
  1740.     parenthesis, to force CHASM to recognize it as an expression:
  1741.  
  1742.           MOV AX, (OFFSET(BUFFER)*(3+2))  ;correct
  1743.  
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750.  
  1751.  
  1752.  
  1753.  
  1754.  
  1755.  
  1756.  
  1757.  
  1758.  
  1759.  
  1760.  
  1761.  
  1762.  
  1763.  
  1764.  
  1765.  
  1766.  
  1767.  
  1768.  
  1769.  
  1770.  
  1771.  
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779.  
  1780.  
  1781.  
  1782.  
  1783.                                                                    25
  1784.  
  1785.     >>Resolution of Ambiguities<<
  1786.  
  1787.     The language defined in "The 8086 Book" contains a number of
  1788.     ambiguities which must be resolved by an assembler.  This is
  1789.     discussed throughout the book, but pages 3-285 and 3-286
  1790.     specifically cover this topic.  CHASM's solutions of these
  1791.     problems are discussed in this section.
  1792.  
  1793.     A. 8088 Memory references:
  1794.  
  1795.     When one specifies the address of a memory location, it is
  1796.     unclear how large an operand is being referenced.  An operand
  1797.     might be a byte, or a word.
  1798.  
  1799.        1. If a register is present as an operand, it is assumed that
  1800.           the memory operand matches the register in size.  An
  1801.           exception to this rule are the shift and rotate
  1802.           instructions, where the CL register is used as a counter,
  1803.           and has nothing to do with the size of the other operand.
  1804.           Examples:
  1805.  
  1806.           MOV MASK, AX  ;mask is a word
  1807.           MOV DH, [BX]  ;BX points to a byte
  1808.           NEG [SI]      ;error, operand of unknown size
  1809.           SHR FLAG, CL  ;error, flag is of unknown size
  1810.  
  1811.        2. If no register is present, (or if the only register is CL
  1812.           being used as a counter) the size of the memory operand is
  1813.           specified by adding the suffix "B" or "W" to the
  1814.           instruction mnemonic.  Examples:
  1815.  
  1816.           NEGB [SI]        ;SI points to a byte
  1817.           SHRW FLAG, CL    ;flag is a word
  1818.           MOVW MASK, 0AH   ;mask is a word
  1819.           MOVB MASK, 0AH   ;mask is a byte
  1820.           MOVW MASK, 9A9AH ;must specify size even though
  1821.                            ;immediate operand implies word
  1822.  
  1823.  
  1824.  
  1825.  
  1826.  
  1827.  
  1828.  
  1829.  
  1830.  
  1831.  
  1832.  
  1833.  
  1834.  
  1835.  
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.  
  1842.  
  1843.  
  1844.  
  1845.  
  1846.  
  1847.  
  1848.  
  1849.                                                                    26
  1850.  
  1851.     B. 8087 Memory References:
  1852.  
  1853.        All real and integer 8087 memory references are ambiguous as
  1854.        to the operand size.  Integer operands could be word, short,
  1855.        or long.  Reals can be short, long or temporary real.  As with
  1856.        8088 memory references, you specify the size using a suffix:
  1857.  
  1858.              W: word
  1859.              S: short
  1860.              L: long
  1861.              T: temporary real
  1862.  
  1863.        For more details and examples, see the section on 8087
  1864.        support.
  1865.  
  1866.     C. Indirect Branching.
  1867.  
  1868.     The 8088 supports two flavors of indirect branching: intra, and
  1869.     intersegment.  A register is set to point at a memory location
  1870.     which contains a new value for the program counter, and in the
  1871.     case of intersegment branching, a new value for the CS register
  1872.     as well.
  1873.  
  1874.     The syntax of "The 8086 Book" does not specify which flavor of
  1875.     branch is being invoked.  CHASM adds the suffixes "N" (for near,
  1876.     or intrasegment) and "F" (for far, or intersegment) to the
  1877.     indirect CALL and JMP mnemonics.  Examples:
  1878.  
  1879.        CALLN [BX]    ;intrasegment call
  1880.        JMPF  [DI]    ;intersegment jump
  1881.        JMP   [BP]    ;error, unspecified flavor
  1882.  
  1883.     D. Long and Short Jumps
  1884.  
  1885.     Two types of relative jumps are supported by the 8088: short
  1886.     (specified by a signed 8 bit displacement) and long (specified by
  1887.     a 16 bit displacement).  Both are implemented in CHASM as a jump
  1888.     to a label.
  1889.  
  1890.     The short jump is specified by mnemonic JMPS. Since one of the
  1891.     displacement bits is used to indicate direction, only seven are
  1892.     left to express the magnitude of jump.  JMPS (and similarly, all
  1893.     the jump on condition instructions) is thus limited to branching
  1894.     to labels within a range of -128 to +127 bytes.
  1895.  
  1896.  
  1897.  
  1898.  
  1899.  
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.  
  1906.  
  1907.  
  1908.  
  1909.  
  1910.  
  1911.  
  1912.  
  1913.  
  1914.  
  1915.                                                                    27
  1916.  
  1917.     CHASM reserves mnemonic JMP for the long jump.  JMP may be used
  1918.     to jump anywhere within the program segment, but the object code
  1919.     generated is less compact than that from JMPS.
  1920.  
  1921.     Examples:
  1922.  
  1923.        START PROC NEAR
  1924.              JMPS END     ;short jump
  1925.              JMP  START   ;long jump
  1926.        END   ENDP
  1927.  
  1928.  
  1929.     E. Instruction Prefixes.
  1930.  
  1931.     The 8088 supports three instruction prefixes:
  1932.  
  1933.        1. SEG: segment override. An alternate segment register is
  1934.           specified for a reference to memory.
  1935.  
  1936.        2. REP, REPE,REPNE,REPZ,REPNZ: repeat. A string primitive is
  1937.           repeated until a condition is met.
  1938.  
  1939.        3. LOCK: Turns on the LOCK signal. Only useful in
  1940.           multi-processor situations.
  1941.  
  1942.     SEG is implemented as a modifier attached to a memory operand.
  1943.     If you want to override the default segment register for a memory
  1944.     access, precede the memory operand with the segment register
  1945.     followed by a colon.  Examples:
  1946.  
  1947.        MOV AX, ES:FLAG     ;flag is in the extra segment
  1948.        MOV CS:[100H], DX   ;offset 100H in the code segment
  1949.  
  1950.  
  1951.  
  1952.  
  1953.  
  1954.  
  1955.  
  1956.  
  1957.  
  1958.  
  1959.  
  1960.  
  1961.  
  1962.  
  1963.  
  1964.  
  1965.  
  1966.  
  1967.  
  1968.  
  1969.  
  1970.  
  1971.  
  1972.  
  1973.  
  1974.  
  1975.  
  1976.  
  1977.  
  1978.  
  1979.  
  1980.  
  1981.                                                                    28
  1982.  
  1983.     The other prefixes are implemented as separate instructions. They
  1984.     appear on a separate line, immediately before the instruction
  1985.     which they modify.  For compatibility with earlier versions of
  1986.     CHASM, you can also specify segment overrides on a separate line,
  1987.     using the mnemonic SEG. Examples:
  1988.  
  1989.        REP
  1990.        MOVSB           ;move bytes until CX decremented to 0
  1991.        SEG SS
  1992.        MOV AX,BUFFER   ;buffer is in the stack segment
  1993.        LOCK
  1994.        MOV [8FFH], AX  ;lock bus to ensure data is transferred
  1995.                        ;before other processors try to access it
  1996.  
  1997.     Note for 8087 users:  You may get unexpected results using the
  1998.        separate instruction form of SEG on 8087 instructions.  Use
  1999.        the operand modifier form for segment overrides on 8087
  2000.        instructions.
  2001.  
  2002.  
  2003.  
  2004.  
  2005.  
  2006.  
  2007.  
  2008.  
  2009.  
  2010.  
  2011.  
  2012.  
  2013.  
  2014.  
  2015.  
  2016.  
  2017.  
  2018.  
  2019.  
  2020.  
  2021.  
  2022.  
  2023.  
  2024.  
  2025.  
  2026.  
  2027.  
  2028.  
  2029.  
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.  
  2044.  
  2045.  
  2046.  
  2047.                                                                    29
  2048.  
  2049.     >>Pseudo-Operations<<
  2050.  
  2051.     The following pseudo-ops are implemented:
  2052.  
  2053.     A. BSAVE: Generate object code in BSAVE format.
  2054.  
  2055.        Instructs CHASM to build a header in the format of BASIC's
  2056.        BSAVE command.  The resulting object code file may be BLOADed
  2057.        by BASIC programs.  No operands are required, and the
  2058.        pseudo-op may appear anywhere within the source code.
  2059.        Example: 
  2060.  
  2061.              ORG    0     ;no psp
  2062.        SUBRT PROC   FAR   ;subroutine for BASIC program
  2063.              BSAVE        ;make BLOADable object file
  2064.  
  2065.     B. COUNT ...ENDC:  Count bytes.
  2066.  
  2067.        COUNT was available in earlier versions of CHASM. With the
  2068.        addition of operand expression support, COUNT became obsolete,
  2069.        and was eliminated to make room for new features.
  2070.  
  2071.        Existing programs using COUNT can be modified as in the
  2072.        following example.  The length of the string is calculated by
  2073.        subtracting two labels, one just before the string, one just
  2074.        after it:
  2075.  
  2076.        MESSAGE    COUNT
  2077.        MSG_TXT    DB   'This utility requires DOS 2.0!' beep cr lf
  2078.                   ENDC
  2079.                   MOV CX, LENGTH(MESSAGE)
  2080.  
  2081.        becomes:
  2082.  
  2083.        MSG_TXT    DB   'This utility requires DOS 2.0!' beep cr lf
  2084.        MSG_END
  2085.                   MOV   CX, MSG_END-MSG_TXT
  2086.  
  2087.  
  2088.  
  2089.  
  2090.  
  2091.  
  2092.  
  2093.  
  2094.  
  2095.  
  2096.  
  2097.  
  2098.  
  2099.  
  2100.  
  2101.  
  2102.  
  2103.  
  2104.  
  2105.  
  2106.  
  2107.  
  2108.  
  2109.  
  2110.  
  2111.  
  2112.  
  2113.                                                                    30
  2114.  
  2115.     C. DB: Declare Bytes
  2116.  
  2117.        Memory locations are filled with values from the operand list.
  2118.        Any number of operands may appear, but all must fit on one
  2119.        line. Acceptable operands are immediate data, or strings
  2120.        enclosed in single quotes (').  DB interprets strings as a
  2121.        series of ASCII bytes.
  2122.  
  2123.        If a label appears, it is redefined as a memory location, and
  2124.        the data area may be referred to using the label, rather than
  2125.        an address. Examples:
  2126.  
  2127.              MOV AX,MASK
  2128.        MASK  DB  00H,01H
  2129.        STG   DB  'A string operand'
  2130.  
  2131.        CHASM generates an error message ("Data too large") if word
  2132.        operands (such as OFFSETs, or numbers greater than 255) are
  2133.        found in the DB operand list. DW should be used for declaring
  2134.        words.
  2135.  
  2136.     D. DM: Declare Multiple Bytes
  2137.  
  2138.        Like COUNT, DM became obsolete when operand expressions became
  2139.        available, and has been eliminated to make room for new
  2140.        features.  Existing programs using DM can be modified as
  2141.        follows:
  2142.  
  2143.            DM  500, ENTRYLENGTH
  2144.  
  2145.        becomes:
  2146.  
  2147.            DS  500*ENTRYLENGTH
  2148.  
  2149.  
  2150.  
  2151.  
  2152.  
  2153.  
  2154.  
  2155.  
  2156.  
  2157.  
  2158.  
  2159.  
  2160.  
  2161.  
  2162.  
  2163.  
  2164.  
  2165.  
  2166.  
  2167.  
  2168.  
  2169.  
  2170.  
  2171.  
  2172.  
  2173.  
  2174.  
  2175.  
  2176.  
  2177.  
  2178.  
  2179.                                                                    31
  2180.  
  2181.     E. DS: Declare Storage
  2182.  
  2183.        Used to declare large blocks of identically initialized
  2184.        storage.  The first operand is required, a number specifying
  2185.        how many bytes are declared.  If a second operand in the form
  2186.        of a number 0-FFH appears, the locations will all be
  2187.        initialized to this value.  If the second operand is not
  2188.        present, locations are initialized to 0.   As with DB, any
  2189.        label is redefined as a memory location.  To save space, the
  2190.        object code does not appear on the listing.  Examples:
  2191.  
  2192.           DS 10         ;10 locs initialized to 0
  2193.           DS 100H,1AH   ;256 locs initialized to 1AH
  2194.  
  2195.     F. DW: Declare Words
  2196.  
  2197.        Used to unambiguously assign a word of storage for each item
  2198.        in the operand list.  Any number of immediate operands may
  2199.        appear, but all must fit on one line.  As with DB, any label
  2200.        is redefined as a memory location. Example:
  2201.  
  2202.            DW 0012H, FFFFH       ;four bytes declared
  2203.  
  2204.     G. EJECT: Begin New Print Page
  2205.  
  2206.        When listing is enabled, causes CHASM to move to the top of
  2207.        the next listing page.  Normally has no effect on listings
  2208.        sent to the screen or to disk, although you can enable EJECTs
  2209.        in disk listings with CHASM's /DPAGE configuration switch.
  2210.  
  2211.     H. EJECTIF: Conditional Page Break
  2212.  
  2213.        Requires one immediate operand.  If listing is enabled
  2214.        and fewer than that many lines are left on the current page of
  2215.        the listing, CHASM will move to the top of the next page.
  2216.  
  2217.        If you put an appropriate EJECTIF at the beginning of each
  2218.        procedure or section of your programs, CHASM will keep them in
  2219.        one piece.  Like EJECT, EJECTIF normally has no effect on
  2220.        listings to the screen or disk.  You can enable EJECTIF for
  2221.        disk listings with CHASM's /DPAGE configuration switch.
  2222.        Example:
  2223.  
  2224.            EJECTIF 20    ;following procedure is 20 lines long
  2225.  
  2226.  
  2227.  
  2228.  
  2229.  
  2230.  
  2231.  
  2232.  
  2233.  
  2234.  
  2235.  
  2236.  
  2237.  
  2238.  
  2239.  
  2240.  
  2241.  
  2242.  
  2243.  
  2244.  
  2245.                                                                    32
  2246.  
  2247.     I. ENDP: End of Procedure
  2248.  
  2249.        See PROC (below) for details.
  2250.  
  2251.     J. ENDSTRUC: End of Structure
  2252.  
  2253.        ==>Advanced version only.  See STRUC (below) for details.
  2254.  
  2255.     K. EQU: Equate
  2256.  
  2257.        Used to equate a symbolic name with a number. The symbol may
  2258.        then be used anywhere the number would be used.  Use of
  2259.        symbols makes programs more understandable, and simplifies
  2260.        modification.
  2261.  
  2262.        An alternate form of EQU encloses the number in square
  2263.        brackets: []. The symbol is then interpreted as a memory
  2264.        location, and may be used as an address for memory access.
  2265.        This version is provided to allow symbolic reference to
  2266.        locations outside the program segment. Examples:
  2267.  
  2268.           MOFFSET    EQU 0B000H
  2269.           MONOCHROME EQU [0000H]
  2270.  
  2271.        Warning: Difficult to debug errors may result from using a
  2272.        ======>  symbol prior to its being defined by EQU.  You are
  2273.                 strongly urged to group all your equates together at
  2274.                 the beginning of programs, before any other
  2275.                 instructions. See "Phase Error" in the Error Message
  2276.                 section.
  2277.  
  2278.     L. INLINE: Generate Turbo Pascal inline statements
  2279.  
  2280.        Instructs CHASM to output object code in the form of a text
  2281.        file, suitable for including in Turbo Pascal inline
  2282.        statements.  The resulting object file is not directly
  2283.        executable, but with minimal editing, can be compiled by Turbo
  2284.        Pascal as inline data.
  2285.  
  2286.        INLINE can appear anywhere in your source file, and requires
  2287.        no operands.
  2288.  
  2289.        See the "Execution of Assembled Programs" section of this
  2290.        document for examples, and more details.
  2291.  
  2292.  
  2293.  
  2294.  
  2295.  
  2296.  
  2297.  
  2298.  
  2299.  
  2300.  
  2301.  
  2302.  
  2303.  
  2304.  
  2305.  
  2306.  
  2307.  
  2308.  
  2309.  
  2310.  
  2311.                                                                    33
  2312.  
  2313.     M. IFXX... [ELSE]... ENDIF: Conditional Assembly
  2314.  
  2315.        ===> Advanced version only.
  2316.  
  2317.        CHASM's conditional assembly pseudo-ops can be used to cause
  2318.        macros to expand differently according to the parameters
  2319.        supplied on the invocation.  Many different IF pseudo-ops are
  2320.        provided, to allow testing for (in)equality, relative size,
  2321.        and (non)existence of parameters.  You can also test whether a
  2322.        parameter is a register, and if so, what type.
  2323.  
  2324.        For more details and examples, see the Macro section of this
  2325.        document.
  2326.  
  2327.     N. INCLUDE: Include file
  2328.  
  2329.        ==>Advanced version only.
  2330.  
  2331.        INCLUDE requires one string operand, a filename enclosed in
  2332.        single quotes.  If desired, you can specify a drive and/or a
  2333.        path as part of the filename.
  2334.  
  2335.        The contents of the specified file are logically inserted into
  2336.        the source file at the point where the INCLUDE appears.
  2337.        INCLUDEs cannot be nested: an error message will be printed if
  2338.        the specified file itself contains an INCLUDE.  Example:
  2339.  
  2340.            INCLUDE '\ASM\STDIO.HDR'    ;bring in standard library
  2341.  
  2342.     O. LIST: Enable listing output
  2343.  
  2344.        Output to the list device is enabled, presumably after a
  2345.        NOLIST was encountered.  No operands required.
  2346.  
  2347.  
  2348.  
  2349.  
  2350.  
  2351.  
  2352.  
  2353.  
  2354.  
  2355.  
  2356.  
  2357.  
  2358.  
  2359.  
  2360.  
  2361.  
  2362.  
  2363.  
  2364.  
  2365.  
  2366.  
  2367.  
  2368.  
  2369.  
  2370.  
  2371.  
  2372.  
  2373.  
  2374.  
  2375.  
  2376.  
  2377.                                                                    34
  2378.  
  2379.     P. MACRO ...ENDM: Macro Definition
  2380.  
  2381.        ==> Advanced version only.
  2382.  
  2383.        Declares a macro.  MACRO requires no operands, and signals
  2384.        CHASM that the following lines constitute a macro definition,
  2385.        and are to be stored for later use, rather than assembled in
  2386.        place.  A label is required on the MACRO statement to name the
  2387.        defined macro.
  2388.  
  2389.        ENDM terminates the macro definition, and requires no
  2390.        operands.
  2391.  
  2392.        For more information and examples, see the section titled
  2393.        "Macros".
  2394.  
  2395.     Q. NOLIST: Disable listing output
  2396.  
  2397.        Normal output to the list device is disabled.  Error messages
  2398.        are listed as usual.  No operands required.
  2399.  
  2400.     R. ORG: Origin
  2401.  
  2402.        Allows direct manipulation of the location counter during
  2403.        assembly.  By default, CHASM assembles code to start at offset
  2404.        100H, thus leaving room for the program segment prefix
  2405.        normally built by COMMAND or DEBUG.  In situations where no
  2406.        PSP is provided, such as routines to be called from BASIC, you
  2407.        should override this default with ORG, or incorrect assembly
  2408.        may result.
  2409.  
  2410.        ORG requires one operand, a number between 0 and FFFFH, which
  2411.        represents the new setting of CHASM's location counter.
  2412.        Although the location counter may be reset anywhere within a
  2413.        program, generally this pseudo-op should be used before any
  2414.        machine executable instructions for meaningful results.
  2415.  
  2416.        Example:
  2417.  
  2418.          ORG 0   ;Code will be assembled for starting
  2419.                  ;offset of 0
  2420.  
  2421.  
  2422.  
  2423.  
  2424.  
  2425.  
  2426.  
  2427.  
  2428.  
  2429.  
  2430.  
  2431.  
  2432.  
  2433.  
  2434.  
  2435.  
  2436.  
  2437.  
  2438.  
  2439.  
  2440.  
  2441.  
  2442.  
  2443.                                                                    35
  2444.  
  2445.     S. PROC ...ENDP: Procedure Definition
  2446.  
  2447.        Declares a procedure.  One operand is required on PROC, either
  2448.        the word NEAR, or the word FAR.  This pseudo-op warns CHASM
  2449.        whether to assemble returns as intra (near) or intersegment
  2450.        (far).  Procedures called from within the program being
  2451.        assembled should be declared NEAR.  Generally, all others
  2452.        should be FAR.  ENDP terminates the procedure, and requires no
  2453.        operands.  If a RET is encountered outside of a declared
  2454.        procedure, an error occurs.  Procedures may be nested, up to
  2455.        10 deep.  Example:
  2456.  
  2457.        MAIN  PROC  FAR
  2458.              ...
  2459.              ...      ;body of procedure
  2460.              ENDP
  2461.  
  2462.     T. RADIX:  Default Number Base
  2463.  
  2464.        CHASM's default radix is 10, meaning that numbers are assumed
  2465.        to be in base 10 unless they end in "B" or "H".  The RADIX
  2466.        pseudo-op allows you to change this default.  Allowed RADIX
  2467.        values are 16 and 10.  Setting RADIX 16 allows you to specify
  2468.        hex numbers without the trailing "H".
  2469.  
  2470.        Note that when RADIX 16 is in effect, there is no way to
  2471.        specify numbers in base 1 (binary) or base 10 (decimal).  To
  2472.        write in either of these bases, shift back to RADIX 10.  For
  2473.        example:
  2474.  
  2475.           RADIX 16
  2476.           mov   ax, 1B     ;means 1B in hexadecimal
  2477.           mov   ax, 20     ;means 20 in hexadecimal
  2478.           mov   ax, 30H    ;trailing "H" allowed, but not necessary
  2479.           RADIX 10
  2480.           mov   ax, 1B     ;means 1 in binary
  2481.           mov   ax, 20     ;means 20 in decimal
  2482.           mov   ax, 30H    ;means 30 in hexadecimal
  2483.  
  2484.  
  2485.  
  2486.  
  2487.  
  2488.  
  2489.  
  2490.  
  2491.  
  2492.  
  2493.  
  2494.  
  2495.  
  2496.  
  2497.  
  2498.  
  2499.  
  2500.  
  2501.  
  2502.  
  2503.  
  2504.  
  2505.  
  2506.  
  2507.  
  2508.  
  2509.                                                                    36
  2510.  
  2511.     U. STRUC ...ENDSTRUC: Structure Definition
  2512.  
  2513.        ==> Advanced version only.
  2514.  
  2515.        Declares a structure.  STRUC requires no operands, and signals
  2516.        CHASM that the following lines constitute a structure
  2517.        template, and not actual storage declaration.  If a label
  2518.        appears on the STRUC, the label is equated with the length of
  2519.        the structure.
  2520.  
  2521.        ENDSTRUC terminates the structure definition, and requires no
  2522.        operands.
  2523.  
  2524.        Inside the structure, storage defining pseudo-ops behave
  2525.        somewhat differently.  See the section titled "Structures" for
  2526.        more information. Example:
  2527.  
  2528.            DIRENTRY STRUC      ;disk directory entry
  2529.            NAME     DS    8
  2530.            EXT      DS    3
  2531.            ATRIB    DS    1
  2532.            RESERVED DS   10
  2533.            TIME     DS    2
  2534.            DATE     DS    2
  2535.            START    DS    2
  2536.            SIZE     DS    4
  2537.                     ENDSTRUC
  2538.  
  2539.  
  2540.     V. WAITON / WAITOFF: Toggle Automatic WAIT Assembly
  2541.  
  2542.        CHASM normally assembles WAIT instructions before most 8087
  2543.        instructions.  After a WAITOFF pseudo-op is encountered, CHASM
  2544.        will not add WAITs.  This allows you to let the 8088 and 8087
  2545.        run in parallel for greater speed, putting in WAITs manually
  2546.        where synchronization is important.  WAITON turns automatic
  2547.        WAIT assembly back on.
  2548.  
  2549.     W. CHKJMP / NOCHKJMP
  2550.  
  2551.        Following a CHKJMP pseudo-op, CHASM will check each JMP
  2552.        instruction to see if it could have been coded as JMPS (to
  2553.        produce tighter code).  JMP instructions with displacements
  2554.        smaller than 128 bytes will be flagged with a diagnostic
  2555.        message ("Could Use JMPS").  NOCHKJMP turns off JMP checking.
  2556.  
  2557.  
  2558.  
  2559.  
  2560.  
  2561.  
  2562.  
  2563.  
  2564.  
  2565.  
  2566.  
  2567.  
  2568.  
  2569.  
  2570.  
  2571.  
  2572.  
  2573.  
  2574.  
  2575.                                                                    37
  2576.  
  2577.  
  2578.     X. = : Assignment to Assembler Variable
  2579.  
  2580.        CHASM supports the use of "assembler variables", which can be
  2581.        dynamically redefined throughout your program.  The assignment
  2582.        operator "=" acts similarly to pseudo-op EQU.  A label on a
  2583.        "=" line will be defined as equivalent to the operand, until
  2584.        it is redefined by another assignment statement.  Unlike EQU,
  2585.        with "=" you can assign any valid operand type (except string)
  2586.        to the assembler variable. These assignments do *NOT* result
  2587.        in object code generation - they simply redefine a symbol to
  2588.        have different meanings to CHASM in different parts of your
  2589.        program.  For example:
  2590.  
  2591.        x    =   [80]
  2592.             mov ax, x      ;means mov ax, [80]
  2593.        x    =   bx
  2594.             mov ax, x      ;x  redefined, means mov ax, bx
  2595.        x    =   100H
  2596.             mov ax, x      ;redefined again, means mov ax, 100H
  2597.  
  2598.  
  2599.  
  2600.  
  2601.  
  2602.  
  2603.  
  2604.  
  2605.  
  2606.  
  2607.  
  2608.  
  2609.  
  2610.  
  2611.  
  2612.  
  2613.  
  2614.  
  2615.  
  2616.  
  2617.  
  2618.  
  2619.  
  2620.  
  2621.  
  2622.  
  2623.  
  2624.  
  2625.  
  2626.  
  2627.  
  2628.  
  2629.  
  2630.  
  2631.  
  2632.  
  2633.  
  2634.  
  2635.  
  2636.  
  2637.  
  2638.  
  2639.  
  2640.  
  2641.                                                                    38
  2642.  
  2643.     >>Macros<<
  2644.  
  2645.     ==>Advanced version only.
  2646.  
  2647.     Macros are an advanced feature.  Beginners may wish to skip this
  2648.     section until they become more experienced with CHASM and
  2649.     assembly language programming.
  2650.  
  2651.     A. Introduction
  2652.  
  2653.        Macros are a shorthand way of writing frequently used
  2654.        sections of code.  Using macros, you can write a code fragment
  2655.        once, then any time you want to use it, just reference it by
  2656.        name.  Once you define a macro and give it a name, anywhere
  2657.        CHASM sees the name will be automatically "expanded" into the
  2658.        previously defined code.
  2659.  
  2660.        For example, suppose you were writing a large program, and at
  2661.        the beginning of each subroutine you pushed all the general
  2662.        purpose registers onto the stack to save their contents.
  2663.        Every subroutine would start out something like this:
  2664.  
  2665.              push ax       ;save register contents
  2666.              push bx
  2667.              push cx
  2668.              push dx
  2669.  
  2670.        Before long, you'd get pretty sick of writing the same thing
  2671.        for each subroutine.  Macros are a way to put some of the
  2672.        boring, repetitive nature of assembly language into the hands
  2673.        of the assembler, freeing you up for the more creative
  2674.        aspects.  Here's how you define a CHASM macro to take the
  2675.        place of this code fragment:
  2676.  
  2677.        savestate  macro
  2678.                   push ax           ;save general purpose registers
  2679.                   push bx
  2680.                   push cx
  2681.                   push dx
  2682.                   endm
  2683.  
  2684.  
  2685.  
  2686.  
  2687.  
  2688.  
  2689.  
  2690.  
  2691.  
  2692.  
  2693.  
  2694.  
  2695.  
  2696.  
  2697.  
  2698.  
  2699.  
  2700.  
  2701.  
  2702.  
  2703.  
  2704.  
  2705.  
  2706.  
  2707.                                                                    39
  2708.  
  2709.        Note the MACRO and ENDM statements.  These signal to CHASM
  2710.        that the enclosed code is a macro definition to be saved for
  2711.        later use, rather than code to be assembled at this point in
  2712.        your program.  The MACRO statement also gives a name
  2713.        (SAVESTATE) to the macro, which will take the place of the
  2714.        stored code.
  2715.  
  2716.        Now, at the beginning of each subroutine you can just write
  2717.        "SAVESTATE" when you want to push the general purpose
  2718.        registers. Here's an example:
  2719.  
  2720.        get_input  proc  near
  2721.                   savestate
  2722.                   ...
  2723.                   ...
  2724.                   endp
  2725.  
  2726.        Given the previous macro definition, the above example is
  2727.        *exactly* equivalent to:
  2728.  
  2729.        get_input  proc  near
  2730.                   push ax
  2731.                   push bx
  2732.                   push cx
  2733.                   push dx
  2734.                   ...
  2735.                   ...
  2736.                   endp
  2737.  
  2738.        The only difference is that less busy work is required on your
  2739.        part.
  2740.  
  2741.        Macros are NOT subroutines!  Subroutines are coded once, then
  2742.        called within your program at run time.  Macros are expanded
  2743.        in-line at assembly time, and the code is inserted into your
  2744.        program at the invocation point.  If you invoke the macro 20
  2745.        times in your program, you'll end up with 20 copies of the
  2746.        macro code. 
  2747.  
  2748.  
  2749.  
  2750.  
  2751.  
  2752.  
  2753.  
  2754.  
  2755.  
  2756.  
  2757.  
  2758.  
  2759.  
  2760.  
  2761.  
  2762.  
  2763.  
  2764.  
  2765.  
  2766.  
  2767.  
  2768.  
  2769.  
  2770.  
  2771.  
  2772.  
  2773.                                                                    40
  2774.  
  2775.        Although this does waste some memory space, you save execution
  2776.        time by eliminating the subroutine call and return process.
  2777.        At a minimum, it takes 32 machine cycles to call a subroutine.
  2778.        The four instruction macro given above requires 40 cycles to
  2779.        execute.  If it were coded as a subroutine, the time to
  2780.        execute it would almost *double*.  Macros trade off space for
  2781.        speed.
  2782.  
  2783.     B. Macro Parameters
  2784.  
  2785.        CHASM's macros allow 9 user defined parameters, which are
  2786.        evaluated at expansion time.  The parameters work just like
  2787.        those in DOS batch files.  Here's an example of a macro with
  2788.        one parameter.  PRINT calls DOS function 9 to print a string
  2789.        on the console.  A parameter is used to specify the name of
  2790.        the string to be printed:
  2791.  
  2792.        print    macro
  2793.                 mov  ah, 09H          ;specify print string function
  2794.                 mov  dx, offset(%1)   ;point to string
  2795.                 int  21H              ;call DOS
  2796.                 endm
  2797.  
  2798.        Given this definition, when CHASM sees a line like:
  2799.  
  2800.              print title
  2801.  
  2802.        The following code gets inserted in its place:
  2803.  
  2804.              mov  ah, 09H
  2805.              mov  dx, offset(title)
  2806.              int  21H
  2807.  
  2808.        Note how the "%1" in the macro definition got replaced by
  2809.        "title" which was put as an operand on the invocation of the
  2810.        macro.  You can put up to 9 operands onto a macro invocation,
  2811.        and they will be substituted for the dummy parameters %1
  2812.        through %9.
  2813.  
  2814.  
  2815.  
  2816.  
  2817.  
  2818.  
  2819.  
  2820.  
  2821.  
  2822.  
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831.  
  2832.  
  2833.  
  2834.  
  2835.  
  2836.  
  2837.  
  2838.  
  2839.                                                                    41
  2840.  
  2841.        If you put a label on a macro invocation, two things happen.
  2842.        As usual, the label represents a program location for
  2843.        branching, with offset equal to the beginning of the expanded
  2844.        macro.  You can branch into the expanded macro by using the
  2845.        label as an operand on a jump or call instruction.  In
  2846.        addition, if the special dummy parameter "%0" is used in the
  2847.        macro definition, it is replaced with the label text when the
  2848.        macro is expanded.  This feature is provided to facilitate
  2849.        writing loops within macros.
  2850.  
  2851.        If you fail to provide an operand for any dummy parameter used
  2852.        in the macro definition, CHASM substitutes a null string of
  2853.        length zero.  To leave one parameter blank, but provide
  2854.        replacements for parameters with higher numbers, use the
  2855.        special operand "%B" for the one you want blank.  For example:
  2856.  
  2857.             def_mem  macro
  2858.             %1       db  %2, %3
  2859.                      endm
  2860.  
  2861.                      def_mem twobytes, 128, FFH
  2862.                      def_mem %B, 'Hit any key when ready...'
  2863.  
  2864.        Expands to:
  2865.  
  2866.             twobytes  db 128, FFH
  2867.                       db 'Hit any key when ready...'
  2868.  
  2869.     C. Internal Labels
  2870.  
  2871.        A potential problem exists if you put a label on a statement
  2872.        within a macro.  The first time the macro gets invoked,
  2873.        everything works fine.  However, remember that a given label
  2874.        can only be used once.  The second time you invoke the macro,
  2875.        the line with the label will get a "Duplicate definition"
  2876.        error message.
  2877.  
  2878.        CHASM offers "internal labels" for use within macros.  When
  2879.        expanding macros, CHASM replaces these internal labels with a
  2880.        unique text, different for each invocation of the macro.
  2881.  
  2882.  
  2883.  
  2884.  
  2885.  
  2886.  
  2887.  
  2888.  
  2889.  
  2890.  
  2891.  
  2892.  
  2893.  
  2894.  
  2895.  
  2896.  
  2897.  
  2898.  
  2899.  
  2900.  
  2901.  
  2902.  
  2903.  
  2904.  
  2905.                                                                    42
  2906.  
  2907.        Macro internal labels are of the form:
  2908.  
  2909.            %Lx
  2910.  
  2911.        The "%L" signals CHASM that you want an internal label.  The
  2912.        "x" can be any character that isn't a delimiter.  By using
  2913.        different characters, you can define a many different labels
  2914.        in a each macro.
  2915.  
  2916.        Within the macro, you use the internal label symbol just like
  2917.        a normal label.  For example:
  2918.  
  2919.            INTLAB MACRO
  2920.            %LA    MOV AX, DX
  2921.                   JMPS %LA
  2922.                   ENDM
  2923.  
  2924.        Each time this macro is invoked, all occurrences of "%LA" will
  2925.        be replaced with a different text.  (The replacement text will
  2926.        be of the form "%LAnnnn" where "nnnn" is a number.)
  2927.  
  2928.        Using the symbol table dump on your listing, you can figure
  2929.        out what text CHASM used in any given invocation.  DON'T try
  2930.        to use this information to branch into the macro invocation
  2931.        from the outside.  Editing your source file can cause CHASM to
  2932.        use a different substitution text the next time you assemble.
  2933.        Internal labels are intended for macro INTERNAL use only.
  2934.  
  2935.     D. Macro Nesting
  2936.  
  2937.        Macro invocations can be nested, up to 10 deep.  Invocations
  2938.        are maintained on a stack, and each invocation has it's own
  2939.        set of parameters and internal labels.
  2940.  
  2941.        CHASM does not check for recursive macro calls.  If you call a
  2942.        macro from within itself, it's quite possible to get caught in
  2943.        an endless loop.  This can also happen indirectly, where a
  2944.        macro invokes another macro, which ends up calling the first.
  2945.        If you get caught, you can escape by hitting Ctrl-Break.
  2946.  
  2947.        Experienced programmers can use macro recursion along with
  2948.        expressions and conditional assembly to create some really
  2949.        elegant macros.  However, this is definitely not for beginners
  2950.        or the faint of heart.  Enter at your own risk.
  2951.  
  2952.  
  2953.  
  2954.  
  2955.  
  2956.  
  2957.  
  2958.  
  2959.  
  2960.  
  2961.  
  2962.  
  2963.  
  2964.  
  2965.  
  2966.  
  2967.  
  2968.  
  2969.  
  2970.  
  2971.                                                                    43
  2972.  
  2973.     E. Conditional Macro Expansion
  2974.  
  2975.        This advanced feature allows you to write general purpose
  2976.        macros which expand in different ways based on the parameters
  2977.        used on the invocation.
  2978.  
  2979.        For example, suppose you wanted to write a macro to do
  2980.        operating system calls.  Many of the DOS functions just load
  2981.        the function number into AH, then call DOS with an interrupt.
  2982.        Here's a macro to do this:
  2983.  
  2984.        doscall  macro
  2985.                 mov ah, %1
  2986.                 int 21H
  2987.                 endm
  2988.  
  2989.        Given the above definition, "DOSCALL 1" will expand into a
  2990.        call to DOS function #1, keyboard input.
  2991.  
  2992.        Unfortunately, not all DOS calls are quite so simple.  For
  2993.        example, the call for printing a string to the console
  2994.        requires that the offset of the string be loaded into DX.
  2995.        Different system calls are going to require somewhat different
  2996.        handling.  One approach would be to write separate macros for
  2997.        each function.  However, with 87 different functions in DOS 2,
  2998.        this starts to get unwieldy.
  2999.  
  3000.        A more general approach is to incorporate some "intelligence"
  3001.        into the macro, and let it expand differently for different
  3002.        DOS functions.  Here's a slightly more general macro, which
  3003.        loads DX whenever the "print string" function is requested:
  3004.  
  3005.        doscall  macro
  3006.                 mov ah, %1
  3007.                 ife %1 9
  3008.                    mov dx, offset(%2)
  3009.                 endif
  3010.                 int 21H
  3011.                 endm
  3012.  
  3013.  
  3014.  
  3015.  
  3016.  
  3017.  
  3018.  
  3019.  
  3020.  
  3021.  
  3022.  
  3023.  
  3024.  
  3025.  
  3026.  
  3027.  
  3028.  
  3029.  
  3030.  
  3031.  
  3032.  
  3033.  
  3034.  
  3035.  
  3036.  
  3037.                                                                    44
  3038.  
  3039.        "IFE" is short for "If Equal".  The "IFE" and "ENDIF" bracket
  3040.        a line of macro code which will be included during expansion
  3041.        only if the "IFE" statement is satisfied.  In this example,
  3042.        the MOV DX statement will be included only if the first
  3043.        parameter is equal to 9.  The enclosed line is indented in
  3044.        this example to help show the structure of the macro, but
  3045.        indentation is not required.
  3046.  
  3047.        Given the above definition, "DOSCALL 1" expands to only two
  3048.        lines:
  3049.  
  3050.           mov ah, 1
  3051.           int 21H
  3052.  
  3053.       However, "DOSCALL 9, STRING" expands to three lines:
  3054.  
  3055.           mov ah, 9
  3056.           mov dx, offset(string)
  3057.           int 21H
  3058.  
  3059.        CHASM supports twelve different conditional test statements.
  3060.        They are:
  3061.  
  3062.             IFE       "if equal"
  3063.             IFNE      "if not equal"
  3064.             IFGT      "if greater than"
  3065.             IFGE      "if greater than or equal"
  3066.             IFLE      "if less than or equal"
  3067.             IFLT      "if less than"
  3068.             IFB       "if blank"
  3069.             IFNB      "if not blank"
  3070.             IFREG     "if a register"
  3071.             IFREG8    "if an 8 bit register"
  3072.             IFREG16   "if a 16 bit register"
  3073.             IFSEGREG  "if a segment register"
  3074.  
  3075.        Most of the conditionals take two operands, and perform a
  3076.        comparison.  The operands are evaluated, and their values are
  3077.        compared according to the condition being tested.  Strings are
  3078.        compared in the normal alphabetical order sense.  Examples:
  3079.  
  3080.             IFE   15, 0FH       ;is true
  3081.             IFGT  'ABCD' 'EFGH' ;is false
  3082.             IFLE  20H, 128      ;is true
  3083.  
  3084.  
  3085.  
  3086.  
  3087.  
  3088.  
  3089.  
  3090.  
  3091.  
  3092.  
  3093.  
  3094.  
  3095.  
  3096.  
  3097.  
  3098.  
  3099.  
  3100.  
  3101.  
  3102.  
  3103.                                                                    45
  3104.  
  3105.        IFB and IFNB require only one operand, which should be a dummy
  3106.        parameter.  These conditionals test whether the parameter was
  3107.        left "blank" or if a replacement was provided on the
  3108.        invocation.
  3109.  
  3110.        The IFREG conditionals take one operand.  They return true if
  3111.        the operand is a register in the following sets:
  3112.  
  3113.             IFREG:    any register
  3114.             IFREG8:   AH, AL, BH, BL, CH, CL, DH, DL
  3115.             IFREG16:  AX, BX, CX, DX, DI, SI, BP, SP
  3116.             IFSEGREG: CS, DS, ES, SS
  3117.  
  3118.        You can place as many lines as you like between an IF
  3119.        statement and the ENDIF.  All will be included if the
  3120.        condition tested is true, and none will be included if it's
  3121.        false.
  3122.  
  3123.        An optional "ELSE" construct is also provided.  Statements
  3124.        after the ELSE get included only if the tested condition is
  3125.        false. CHASM's conditional assembly syntax can be summarized
  3126.        as follows:
  3127.  
  3128.            IF.....            ;if statement with parameter(s)
  3129.              s1                  ;statements included if true
  3130.              s2                  ;    "         "      "   " 
  3131.            ELSE               ;end of "true" option, begin "false"
  3132.              s3                  ;statements included if false
  3133.              s4                  ;    "         "      "   "
  3134.            ENDIF              ;end of conditional assembly
  3135.  
  3136.        IF statements can be nested, up to 10 deep.  During nesting,
  3137.        CHASM assumes that ELSEs are paired with the latest unfinished
  3138.        IF statement.  For example:
  3139.  
  3140.        example macro
  3141.                ife %1, 1
  3142.                   db 'Outer IF is true'
  3143.                   ifb %2
  3144.                      'Inner IF is true'
  3145.                   else
  3146.                      'Where do I belong?'
  3147.                   endif
  3148.                endif
  3149.  
  3150.  
  3151.  
  3152.  
  3153.  
  3154.  
  3155.  
  3156.  
  3157.  
  3158.  
  3159.  
  3160.  
  3161.  
  3162.  
  3163.  
  3164.  
  3165.  
  3166.  
  3167.  
  3168.  
  3169.                                                                    46
  3170.  
  3171.        "EXAMPLE 1, 5" expands to:
  3172.  
  3173.               db 'Outer IF is true'
  3174.               db 'Where do I belong?'
  3175.  
  3176.        But "EXAMPLE 2" produces no expansion at all.
  3177.  
  3178.        This is easiest to follow if you use "structured" indenting
  3179.        when writing the macro, as in the example above. Remember,
  3180.        however, that CHASM ignores indenting and follows the
  3181.        "latest unfinished" rule in figuring out which IF gets the
  3182.        ELSE.  Don't fool yourself with improper indentation.
  3183.  
  3184.     F. Final Notes:
  3185.  
  3186.        The conditional assembly pseudo-ops are not restricted to use
  3187.        only in macros, although there aren't that many useful
  3188.        non-macro applications.
  3189.  
  3190.        CHASM won't recursively expand parameters.  For example:
  3191.  
  3192.            RECUR MACRO
  3193.                  XOR %1, %2
  3194.                  ENDM
  3195.  
  3196.                  RECUR AX, %1
  3197.  
  3198.        expands to:
  3199.  
  3200.                 XOR AX, %1   ;actual expansion
  3201.  
  3202.        NOT to:
  3203.  
  3204.                 XOR AX, AX   ;won't happen
  3205.  
  3206.        Like equates and structures, macro definitions should all be
  3207.        placed at the beginning of your programs, before the macro
  3208.        gets invoked.  If you invoke a macro before it's defined, a
  3209.        phase error will occur.
  3210.  
  3211.  
  3212.  
  3213.  
  3214.  
  3215.  
  3216.  
  3217.  
  3218.  
  3219.  
  3220.  
  3221.  
  3222.  
  3223.  
  3224.  
  3225.  
  3226.  
  3227.  
  3228.  
  3229.  
  3230.  
  3231.  
  3232.  
  3233.  
  3234.  
  3235.                                                                    47
  3236.  
  3237.        Macro definitions are stored and expanded blindly by CHASM,
  3238.        with no syntax checking.  Dummy parameter symbols can appear
  3239.        in any of the input line fields.  Any errors in a macro
  3240.        definition will only become evident when CHASM expands the
  3241.        macro and attempts to assemble the result.
  3242.  
  3243.        In keeping with the "shorthand" philosophy of macros, the
  3244.        results of macro expansion don't normally appear on the
  3245.        listing.  If you want to see the expansion for debugging
  3246.        purposes, insert a LIST pseudo-op as the first line of the
  3247.        macro definition.
  3248.  
  3249.        Once you start writing macros, you might find it useful to
  3250.        gather them together into a single file.  You can then pull
  3251.        this file into the beginning of all your programs with an
  3252.        INCLUDE pseudo-op.  Macros which don't get invoked won't add
  3253.        anything to the object code produced, and you'll save yourself
  3254.        the trouble of typing in the ones you *do* need.  If you put a
  3255.        NOLIST at the beginning and a LIST at the end of your INCLUDE
  3256.        file, you don't even have to look at the definitions on your
  3257.        listings.
  3258.  
  3259.  
  3260.  
  3261.  
  3262.  
  3263.  
  3264.  
  3265.  
  3266.  
  3267.  
  3268.  
  3269.  
  3270.  
  3271.  
  3272.  
  3273.  
  3274.  
  3275.  
  3276.  
  3277.  
  3278.  
  3279.  
  3280.  
  3281.  
  3282.  
  3283.  
  3284.  
  3285.  
  3286.  
  3287.  
  3288.  
  3289.  
  3290.  
  3291.  
  3292.  
  3293.  
  3294.  
  3295.  
  3296.  
  3297.  
  3298.  
  3299.  
  3300.  
  3301.                                                                    48
  3302.  
  3303.     >>Structures<<
  3304.  
  3305.     ==>Advanced version only.
  3306.  
  3307.     Structures are an advanced feature.  Beginners may wish to skip
  3308.     this section until they become more experienced with CHASM and
  3309.     assembly language programming.
  3310.  
  3311.     CHASM's structure capability allows you to generate a "template"
  3312.     with which to organize repetitive data structures.  As an example
  3313.     of a repetitive data structure, consider a phone list.  Each
  3314.     entry in the list has three components:
  3315.  
  3316.          Name    - 20 characters
  3317.          Address - 50 characters
  3318.          Phone   - 10 characters
  3319.  
  3320.     Each entry thus uses a total of 80 bytes of storage.  To declare
  3321.     a list with 500 entries, you would declare 80 x 500 = 4000 bytes:
  3322.  
  3323.          PHONELIST  DS  4000   ;500 entries @ 80 bytes/entry
  3324.  
  3325.     That's easy enough, but now what's the offset of the 346th
  3326.     address field?  This is starting to get confusing, and time
  3327.     consuming to figure out.
  3328.  
  3329.     Furthermore, hard-coding numbers (like that 4000, above) into a
  3330.     program is never a good idea.  What's going to happen when you
  3331.     decide to add a zip code field, or make more room in the name
  3332.     field because you just met Alexandria Zbrievskivich?  You'd have
  3333.     to go through and change by hand each number which depended on
  3334.     the actual layout of your data.  Murphy's law guarantees that
  3335.     it'll take somewhere between "several" and "too many" assemblies
  3336.     to find them all.
  3337.  
  3338.     Structures allow you to set up a symbolic template which makes it
  3339.     much easier to manage structured data like this phone list.  By
  3340.     using symbols defined in the structure, rather than bare numbers,
  3341.     a change in data structure doesn't mean a frantic search
  3342.     throughout your entire program to make corrections.  If you
  3343.     change the structure definition, the symbols take on new values
  3344.     automatically.
  3345.  
  3346.  
  3347.  
  3348.  
  3349.  
  3350.  
  3351.  
  3352.  
  3353.  
  3354.  
  3355.  
  3356.  
  3357.  
  3358.  
  3359.  
  3360.  
  3361.  
  3362.  
  3363.  
  3364.  
  3365.  
  3366.  
  3367.                                                                    49
  3368.  
  3369.     Here's what the phone list structure looks like:
  3370.  
  3371.          LISTENTRY  STRUC
  3372.          NAME       DS 20
  3373.          ADDRESS    DS 50
  3374.          PHONE      DS 10
  3375.                     ENDSTRUC
  3376.  
  3377.     Note the STRUC and ENDSTRUC statements.  They mark the beginning
  3378.     and end of the structure, and give it a name (LISTENTRY).
  3379.  
  3380.     Within the structure are storage defining pseudo-ops.  DS is used
  3381.     in this example, but DB and DW could also be used.  ORG can be
  3382.     used within a structure, but any 8088 instruction will result in
  3383.     an diagnostic message and termination of the structure
  3384.     definition.
  3385.  
  3386.     Inside a structure, the storage defining pseudo-ops
  3387.     behave somewhat differently than normal.  No actual storage is
  3388.     set aside, but CHASM keeps track of how much space would normally
  3389.     be declared.
  3390.  
  3391.     Labels on pseudo-ops get assigned values equal to their offset
  3392.     within the *structure*, not within the program as a whole.  Also,
  3393.     CHASM will treat the labels as immediate operands, rather than
  3394.     memory locations.  The result of the structure given above is to
  3395.     generate three immediate operands, with the following values:
  3396.  
  3397.          NAME    =  0
  3398.          ADDRESS = 20
  3399.          PHONE   = 70
  3400.  
  3401.     CHASM does one other piece of useful book-keeping during
  3402.     structure definitions.  If a label appears on the STRUC
  3403.     pseudo-op, it gets treated as an immediate operand, whose value
  3404.     is equal to the total length of the structure.
  3405.  
  3406.     You can either use the STRUC label directly as an operand, or if
  3407.     you like "pretty" code, use the LENGTH operator on it.  In this
  3408.     example, both LISTENTRY and LENGTH(LISTENTRY) are immediate
  3409.     operands of value 80.
  3410.  
  3411.     (Inside note: LENGTH is a null operator, provided mainly for
  3412.     aesthetic reasons.  Using LENGTH will often make your code more
  3413.     readable, but is equivalent to using just the label itself.)
  3414.  
  3415.  
  3416.  
  3417.  
  3418.  
  3419.  
  3420.  
  3421.  
  3422.  
  3423.  
  3424.  
  3425.  
  3426.  
  3427.  
  3428.  
  3429.  
  3430.  
  3431.  
  3432.  
  3433.                                                                    50
  3434.  
  3435.     Like equates and macros, structures should be placed at the
  3436.     beginning of your programs before any machine instructions,
  3437.     otherwise phase errors can occur.  If you *do* embed structures
  3438.     inside your program, you can eliminate any phase errors by using
  3439.     the LENGTH function to reference any of the immediate operands
  3440.     generated by the embedded structure.
  3441.  
  3442.     The immediate operands generated during a structure definition
  3443.     can be very useful in writing your program.  Following the phone
  3444.     list example, here's a better way to declare storage for the
  3445.     list:
  3446.  
  3447.        NUMENTRYS  EQU 500
  3448.        PHONELIST  DS  LISTENTRY*NUMENTRYS ;500 entries of length
  3449.                                           ;defined by the structure.
  3450.  
  3451.     Now if you add another field to the structure, PHONELIST will
  3452.     automatically increase in size.
  3453.  
  3454.     The 8088's indirect addressing modes, coupled with structures,
  3455.     make a very powerful combination for accessing structured data in
  3456.     memory.  Suppose AX contains the number of the entry you want to
  3457.     work on.  You can calculate the address of the entry as follows:
  3458.  
  3459.         MOV BX, LENGTH(LISTENTRY)    ;length per entry
  3460.         MUL AX, BX                   ;times entry number
  3461.         ADD AX, OFFSET(PHONELIST)    ;plus the starting offset
  3462.         MOV BX, AX                   ;BX <== frame pointer
  3463.  
  3464.     BX is now a "frame pointer" - it points to the beginning of the
  3465.     desired entry.  You can access the various parts of the entry
  3466.     using the optional displacement field in the indirect address.
  3467.     For example, here's how you would store the letter 'A' into the
  3468.     first byte of the address field:
  3469.  
  3470.          MOV  ADDRESS[BX], 'A'
  3471.  
  3472.     As another example, the following line reads the third letter of
  3473.     the name into the AL register:
  3474.  
  3475.          MOV  AL, NAME+3[BX]
  3476.  
  3477.  
  3478.  
  3479.  
  3480.  
  3481.  
  3482.  
  3483.  
  3484.  
  3485.  
  3486.  
  3487.  
  3488.  
  3489.  
  3490.  
  3491.  
  3492.  
  3493.  
  3494.  
  3495.  
  3496.  
  3497.  
  3498.  
  3499.                                                                    51
  3500.  
  3501.     The first entry in a structure almost invariably has value 0.
  3502.     CHASM "optimizes" indirect addresses with structure-generated
  3503.     constants equal to zero, generating the no-offset form of the
  3504.     address.  In this example:
  3505.  
  3506.         MOV AX, NAME[BX]
  3507.  
  3508.     actually assembles as MOV AX, [BX] rather than MOV AX, 0[BX]
  3509.     The resulting code is more compact, and runs faster.
  3510.  
  3511.     The more complicated indirect modes can be used to scan through
  3512.     or point within the fields.  The following program fragment gets
  3513.     the fourth digit in the phone number:
  3514.  
  3515.          MOV DI, 4             ;specify 4th digit
  3516.          MOV AL, PHONE[BX+DI] ;read it into AL
  3517.  
  3518.     Often times, you'll want to process entries sequentially.  To
  3519.     move to the next entry, you just add the length of the entry to
  3520.     the frame pointer:
  3521.  
  3522.          ADD   BX, LENGTH(LISTENTRY)    ;point to next entry
  3523.  
  3524.     The preceding examples should give you a feel for what you can
  3525.     do with structures, but do not exhaust all the possibilities.
  3526.     Experiment with this feature, and many of your programs will be
  3527.     both more readable and more easily modified.
  3528.  
  3529.  
  3530.  
  3531.  
  3532.  
  3533.  
  3534.  
  3535.  
  3536.  
  3537.  
  3538.  
  3539.  
  3540.  
  3541.  
  3542.  
  3543.  
  3544.  
  3545.  
  3546.  
  3547.  
  3548.  
  3549.  
  3550.  
  3551.  
  3552.  
  3553.  
  3554.  
  3555.  
  3556.  
  3557.  
  3558.  
  3559.  
  3560.  
  3561.  
  3562.  
  3563.  
  3564.  
  3565.                                                                    52
  3566.  
  3567.     >>8087 Support<<
  3568.  
  3569.     ===> Advanced version only.
  3570.  
  3571.     In addition to the normal 8088 instructions, CHASM's Advanced
  3572.     version supports all the 8087 mnemonics.  Look in the appendices
  3573.     for a list available instructions.
  3574.  
  3575.     Several books describing the functions of the 8087 instructions
  3576.     are available.  CHASM's 8087 support is based on Appendix D of
  3577.     Intel's 8087 Support Library, and the book "Assembly Language
  3578.     Programming for the IBM Personal Computer" by David J. Bradley
  3579.     (Prentice-Hall, 1984).
  3580.  
  3581.     ALL the 8087 instructions that reference memory for a real or
  3582.     integer quantity are ambiguous as to the size of operand.
  3583.     Integers can be Word (2 bytes), Short (4 bytes) , or Long (8
  3584.     bytes).  Reals can be Short (4 bytes), Long (8 bytes) or
  3585.     Temporary Real (10 bytes).
  3586.  
  3587.     As with 8088 memory references, CHASM resolves ambiguities using
  3588.     a suffix.  The following suffixes can be added to mnemonics to
  3589.     specify operand size:
  3590.  
  3591.        W: word
  3592.        S: short
  3593.        L: long
  3594.        T: temporary real
  3595.  
  3596.     Here are some examples of using suffixes:
  3597.  
  3598.        FADD   [200H]    ;wrong! ambiguous memory reference
  3599.        FADDT  [200H]    ;add 10 byte temporary real
  3600.        FILD   CS:[DI]   ;wrong! ambiguous memory reference
  3601.        FILDW  CS:[DI]   ;load 2 byte integer
  3602.  
  3603.     CHASM automatically generates a WAIT instructions prior to most
  3604.     8087 instructions.  The only exceptions are the "No Wait"
  3605.     instructions with a "N" as the mnemonic's second letter.
  3606.     Examples:
  3607.  
  3608.         FYL2X   ;automatically preceded by WAIT
  3609.         FNCLEX  ;no wait form of FCLEX
  3610.  
  3611.  
  3612.  
  3613.  
  3614.  
  3615.  
  3616.  
  3617.  
  3618.  
  3619.  
  3620.  
  3621.  
  3622.  
  3623.  
  3624.  
  3625.  
  3626.  
  3627.  
  3628.  
  3629.  
  3630.  
  3631.                                                                    53
  3632.  
  3633.     If you'd prefer to manually add WAITs only where needed to
  3634.     synchronize critical instructions, the WAITOFF pseudo-op disables
  3635.     CHASM's automatic WAIT assembly.  Using fewer WAITs allows the
  3636.     8088 and 8087 to run in parallel more often, giving better
  3637.     performance.  Make sure you synchronize with a WAIT before
  3638.     allowing the 8088 to access a location being modified by the
  3639.     8087.  You can turn CHASM's automatic WAIT assembly back on using
  3640.     a WAITON pseudo-op.
  3641.  
  3642.     You must use the operand modifier form for segment overrides on
  3643.     8087 instructions.  A separate SEG instruction will modify
  3644.     CHASM's automatically generated WAIT instruction, and won't
  3645.     affect the intended 8087 instruction.  Example:
  3646.  
  3647.         SEG CS
  3648.         FLDS [100H]     ;wrong!
  3649.         FLDS CS:[100H]  ;correct
  3650.  
  3651.  
  3652.  
  3653.  
  3654.  
  3655.  
  3656.  
  3657.  
  3658.  
  3659.  
  3660.  
  3661.  
  3662.  
  3663.  
  3664.  
  3665.  
  3666.  
  3667.  
  3668.  
  3669.  
  3670.  
  3671.  
  3672.  
  3673.  
  3674.  
  3675.  
  3676.  
  3677.  
  3678.  
  3679.  
  3680.  
  3681.  
  3682.  
  3683.  
  3684.  
  3685.  
  3686.  
  3687.  
  3688.  
  3689.  
  3690.  
  3691.  
  3692.  
  3693.  
  3694.  
  3695.  
  3696.  
  3697.                                                                    54
  3698.  
  3699.     >>Outside the Program Segment<<
  3700.  
  3701.     As mentioned previously, CHASM does not support multiple segment
  3702.     definitions.  Provision is made for limited access outside of the
  3703.     program segment, however.
  3704.  
  3705.     A. Memory References:
  3706.        To access memory outside the program segment, you move a new
  3707.        segment address into the DS register, then address using
  3708.        offsets in the new segment.  The memory option of the EQU
  3709.        pseudo-op allows you to give a variable name to offsets in
  3710.        other segments. For example, to access DOS's equipment flag:
  3711.  
  3712.           BIOS_DATA   EQU  40H
  3713.           EQUIP_FLAG  EQU  [0010H]
  3714.                       MOV  AX,BIOS_DATA  ;can't move immed. to DS
  3715.                       MOV  DS,AX
  3716.                       MOV  AX,EQUIP_FLAG ;get bios equipment flag
  3717.  
  3718.     B. Code Branching:
  3719.        CHASM supports 4 instructions for branching outside the
  3720.        program segment.
  3721.  
  3722.        1. Direct CALL and JMP
  3723.  
  3724.           New values for the PC and CS registers are included in the
  3725.           instruction as two immediate operands.  Example:
  3726.  
  3727.           BIOS         EQU  0F000H            ;RAM bios segment
  3728.           DISKETTE_IO  EQU  0EC59H            ;disk handler
  3729.                        JMP  DISKETTE_IO,BIOS
  3730.  
  3731.        2. Indirect CALLF and JMPF
  3732.  
  3733.           Four consecutive bytes in memory are initialized with new
  3734.           values for the PC and CS registers.  The CALLF or JMPF then
  3735.           references the address of the new values.  Example:
  3736.  
  3737.           BIOS        EQU   0F000H           ;RAM bios segment
  3738.           PRINTER_IO  EQU   0EFD2H           ;printer routine
  3739.                       MOV   [DI],PRINTER_IO
  3740.                       MOV   2[DI],BIOS
  3741.                       CALLF [DI]
  3742.  
  3743.  
  3744.  
  3745.  
  3746.  
  3747.  
  3748.  
  3749.  
  3750.  
  3751.  
  3752.  
  3753.  
  3754.  
  3755.  
  3756.  
  3757.  
  3758.  
  3759.  
  3760.  
  3761.  
  3762.  
  3763.                                                                    55
  3764.  
  3765.     >>Running CHASM<<
  3766.  
  3767.     A. Prompt Mode
  3768.  
  3769.        From DOS, type:
  3770.  
  3771.          CHASM
  3772.  
  3773.        If you're using the Subset version, a hello screen is printed,
  3774.        followed by the message:
  3775.  
  3776.          Hit Esc to exit, anything else to continue...
  3777.  
  3778.        Advanced CHASM skips the commercial message.
  3779.  
  3780.        You're now presented with a series of prompts:
  3781.  
  3782.           Source code file name? [.asm]
  3783.  
  3784.        Type in the name of the file which contains your program.  If
  3785.        you don't include an extension for the filename, CHASM
  3786.        assumes it to be .ASM.  If CHASM is unable to find the file,
  3787.        it will give you the option of naming another file, or
  3788.        returning to DOS.  Note that anywhere CHASM expects a
  3789.        filename, you can optionally include a drive and/or path.
  3790.  
  3791.        Assuming your file is present, CHASM prompts:
  3792.  
  3793.           Direct listing to Printer (P), Screen (S), or Disk (D)?
  3794.           [nul:]
  3795.  
  3796.        Respond with either an upper or lower case letter.  If you
  3797.        just press enter, no listing will be produced.  If you select
  3798.        "D", CHASM will prompt:
  3799.  
  3800.           Name for listing file? [fname.lst]
  3801.  
  3802.        Type in a name for the listing file.  If you just press ENTER,
  3803.        the name defaults to that of your source file, with an
  3804.        extension of .LST.
  3805.  
  3806.  
  3807.  
  3808.  
  3809.  
  3810.  
  3811.  
  3812.  
  3813.  
  3814.  
  3815.  
  3816.  
  3817.  
  3818.  
  3819.  
  3820.  
  3821.  
  3822.  
  3823.  
  3824.  
  3825.  
  3826.  
  3827.  
  3828.  
  3829.                                                                    56
  3830.  
  3831.        Listing Notes:
  3832.  
  3833.           1. The setting of the /PATH configuration switch controls
  3834.              the exact form of the default list file name.
  3835.  
  3836.           2. Regardless of where the listing is sent, error messages
  3837.              are always echoed to the screen.
  3838.  
  3839.           3. Suppressing the listing will result in faster assembly.
  3840.  
  3841.        The final prompt is:
  3842.  
  3843.           Name for object file? [fname.com]
  3844.  
  3845.        Type in a name for the assembled program.  If you just press
  3846.        ENTER, the name defaults to that of your source file, with an
  3847.        extension of .COM.
  3848.  
  3849.        Note: The setting of the /PATH configuration switch controls
  3850.              the exact form of the default object file name.
  3851.  
  3852.        CHASM now assembles your program.  A status line is maintained
  3853.        on the screen, showing how many lines have been processed,
  3854.        along with how many errors have been discovered.  CHASM makes
  3855.        two passes over your source file, outputting the listing and
  3856.        object code on the second pass.  You can pause assembly at any
  3857.        time by hitting Cntl-S (or just S).  Hitting any key then
  3858.        resumes assembly. You may abort assembly and return to DOS at
  3859.        any time by hitting Esc, Ctrl-C or Ctrl-Break.
  3860.  
  3861.        At the end of the second pass, a final summary of the assembly
  3862.        process is printed.  It will look something like:
  3863.  
  3864.           0 Error(s) detected
  3865.           0 Diagnostic(s) offered
  3866.  
  3867.        954 (3BAH) Bytes of object code generated
  3868.  
  3869.        This information should be self-explanatory.  The number of
  3870.        bytes is given in both decimal and hex format.
  3871.  
  3872.  
  3873.  
  3874.  
  3875.  
  3876.  
  3877.  
  3878.  
  3879.  
  3880.  
  3881.  
  3882.  
  3883.  
  3884.  
  3885.  
  3886.  
  3887.  
  3888.  
  3889.  
  3890.  
  3891.  
  3892.  
  3893.  
  3894.  
  3895.                                                                    57
  3896.  
  3897.        If labels appeared in your program, a dump of the symbol table
  3898.        will follow.  This lists each user-defined symbol, along with
  3899.        its value (in hex). The symbols are printed in alphabetical
  3900.        order.  Each value is preceded by a one-letter code, which
  3901.        tells the symbol's type:
  3902.  
  3903.                 P: a program location
  3904.                 M: a memory location for data
  3905.                 I: immediate data
  3906.  
  3907.        Upon exit, CHASM sets the system variable ERRORLEVEL to
  3908.        (surprise!) the total number of errors discovered in your
  3909.        source file. If you run CHASM from a batch file, you can use
  3910.        this feature to automatically invoke your text editor if
  3911.        errors were discovered.
  3912.  
  3913.     B. Expert Mode:
  3914.  
  3915.        This mode allows you to specify all i/o information on the
  3916.        command line which invokes CHASM.  The syntax is:
  3917.  
  3918.           CHASM sourcefile [p|s|d|/] [listfile|/] [objectfile]
  3919.  
  3920.        Items within brackets ([]) are optional. You may select *one*
  3921.        of any list of items separated by a bar (|).
  3922.  
  3923.        Basically, you just include on the command line all your
  3924.        responses to the normal prompts.  Each response must be
  3925.        separated from the others by either a space or comma.
  3926.  
  3927.        If you don't specify the list device/file or the object file,
  3928.        they default to NUL: and sourcename.COM respectively.  To
  3929.        represent a carriage return (to specify a default choice, but
  3930.        allow modifying a later response) use the character slash (/).
  3931.  
  3932.  
  3933.  
  3934.  
  3935.  
  3936.  
  3937.  
  3938.  
  3939.  
  3940.  
  3941.  
  3942.  
  3943.  
  3944.  
  3945.  
  3946.  
  3947.  
  3948.  
  3949.  
  3950.  
  3951.  
  3952.  
  3953.  
  3954.  
  3955.  
  3956.  
  3957.  
  3958.  
  3959.  
  3960.  
  3961.                                                                    58
  3962.  
  3963.        Expert mode examples:
  3964.  
  3965.           1. Source file is EXAMPLE.ASM, no listing, object file
  3966.              EXAMPLE.COM:
  3967.  
  3968.                 CHASM example
  3969.  
  3970.           2. Source file is SDIR.ASM, list to printer, object file
  3971.              SDIR.COM:
  3972.  
  3973.                 CHASM sdir p
  3974.  
  3975.           3. Source file is MYFILE.PRG, list to disk file MYFILE.LST,
  3976.              object file SUBR.COM:
  3977.  
  3978.                 CHASM myfile.prg d / subr.com
  3979.  
  3980.  
  3981.  
  3982.  
  3983.  
  3984.  
  3985.  
  3986.  
  3987.  
  3988.  
  3989.  
  3990.  
  3991.  
  3992.  
  3993.  
  3994.  
  3995.  
  3996.  
  3997.  
  3998.  
  3999.  
  4000.  
  4001.  
  4002.  
  4003.  
  4004.  
  4005.  
  4006.  
  4007.  
  4008.  
  4009.  
  4010.  
  4011.  
  4012.  
  4013.  
  4014.  
  4015.  
  4016.  
  4017.  
  4018.  
  4019.  
  4020.  
  4021.  
  4022.  
  4023.  
  4024.  
  4025.  
  4026.  
  4027.                                                                    59
  4028.  
  4029.     >>Error and Diagnostic Messages<<
  4030.  
  4031.     Error messages generated on pass one appear on the listing before
  4032.     any source code is printed, and mention the line number to which
  4033.     they refer.  The majority of messages occur during pass two, and
  4034.     will appear in the listing immediately prior to the line which
  4035.     caused the message.  Unless the listing itself is going to the
  4036.     screen, messages and the source line which generated them will be
  4037.     echoed there.
  4038.  
  4039.     Add Leading Zero to Hex Constant: Diagnostic.  The unknown
  4040.        symbol could be interpreted as a hexadecimal number if a
  4041.        leading zero was added.
  4042.  
  4043.     CHASM Internal Error: XX PC: YYYY or
  4044.     CHASM I/O Error: XX PC: YYYY 
  4045.        Sigh. You just discovered a problem in CHASM itself.  Please
  4046.        contact Whitman Software, following the procedure in the
  4047.        appendix on Bug Reporting.
  4048.  
  4049.     Could Use JMPS: Diagnostic.  The specified label requires an
  4050.        offset of less than 128 bytes; specifying the short jump would
  4051.        result in more compact code.  The assembled code is correct,
  4052.        however.
  4053.  
  4054.     Conditional Nested Too Deeply:  IF statements can only be nested
  4055.        10 deep.
  4056.  
  4057.     Data too Large:  You are attempting to use a word of immediate
  4058.        data where only a byte is allowed.
  4059.  
  4060.     DM out of range:  The product of the DM's operands is either
  4061.        negative, or greater than 32767.
  4062.  
  4063.     Duplicate Definition of XXX in (linenum): Pass 1 error.  An
  4064.        attempt was made to define a symbol already present in the
  4065.        symbol table.
  4066.  
  4067.     ELSE without IF: An ELSE was encountered, but no corresponding
  4068.        conditional pseudo-op was found.
  4069.  
  4070.     ENDIF without IF: An ENDIF was encountered, but no corresponding
  4071.        conditional pseudo-op was found.
  4072.  
  4073.     ENDM without MACRO:  An ENDM was encountered, but no
  4074.        corresponding MACRO was found.
  4075.  
  4076.  
  4077.  
  4078.  
  4079.  
  4080.  
  4081.  
  4082.  
  4083.  
  4084.  
  4085.  
  4086.  
  4087.  
  4088.  
  4089.  
  4090.  
  4091.  
  4092.  
  4093.                                                                    60
  4094.  
  4095.  
  4096.     ENDP without PROC: An ENDP was encountered, but no corresponding
  4097.        PROC was found.
  4098.  
  4099.     ENDSTRUC without STRUC: An ENDSTRUC was encountered, but no
  4100.        corresponding STRUC was found.
  4101.  
  4102.     EQU Without Label: No symbol was found to equate with the
  4103.        operand.
  4104.  
  4105.     File not found: XXX in (linenum).  Pass one error.  CHASM was
  4106.        unable to find the file XXX, specified in the INCLUDE
  4107.        pseudo-op.
  4108.  
  4109.     Heap Full: Too many XXX.  Usually a Pass one error.
  4110.        You've run out of memory for the symbol and macro tables.  You
  4111.        shouldn't see this message unless you have only 128K and are
  4112.        assembling a very large program.
  4113.  
  4114.     Illegal Label: XXX in (linenum). Pass one error.  The symbol
  4115.        XXX begins in column one and has as its first character a
  4116.        number, or a plus or minus sign.  Alternatively, you tried to
  4117.        use a reserved word or symbol as a label.
  4118.  
  4119.     Illegal Operation for Structure - ENDSTRUC Implied: Diagnostic.
  4120.        The current line is within a structure, and is not a storage
  4121.        defining pseudo-op.  CHASM generates an ENDSTRUC, which
  4122.        terminates the structure definition, then assembles the line
  4123.        normally.
  4124.  
  4125.     Illegal or Undefined Argument for LENGTH:  The argument for the
  4126.        LENGTH  function was not present in the symbol table as an
  4127.        immediate operand on pass 2.
  4128.  
  4129.     Illegal or Undefined Argument for OFFSET: The argument for the
  4130.        OFFSET function was not present in the symbol table as a near
  4131.        label or memory location on pass 2.
  4132.  
  4133.     Missing ENDM:  The end of the input file was encountered, and at
  4134.        least one MACRO had not been terminated by an ENDM.
  4135.  
  4136.     Missing ENDP: The end of the input file was encountered, and at
  4137.        least one PROC had not been terminated by an ENDP.
  4138.  
  4139.     Missing ENDSTRUC: The end of the input file was encountered, and
  4140.        at least one STRUC had not been terminated by an ENDSTRUC.
  4141.  
  4142.  
  4143.  
  4144.  
  4145.  
  4146.  
  4147.  
  4148.  
  4149.  
  4150.  
  4151.  
  4152.  
  4153.  
  4154.  
  4155.  
  4156.  
  4157.  
  4158.  
  4159.                                                                    61
  4160.  
  4161.  
  4162.     Multiple Segment Overrides are Illegal:  Diagnostic.  You have
  4163.        specified more than one segment override on this instruction.
  4164.        The first override is used, and the other(s) ignored.
  4165.  
  4166.     Nested INCLUDE: An INCLUDE was encountered in an INCLUDEd file.
  4167.        The INCLUDE pseudo-op cannot be nested.
  4168.  
  4169.     Nested Structure: A STRUC was encountered inside a structure.
  4170.        Structures cannot be nested.
  4171.  
  4172.     No Name For Macro:  Diagnostic.  The macro statement did not have
  4173.        a label.  CHASM is unable to give a name to the macro, and you
  4174.        will be unable to reference it.
  4175.  
  4176.     Operands Not Compatible:  The size of the two operands does not
  4177.        match.
  4178.  
  4179.     Phase Error: A label or memory location is found to have
  4180.        different values on pass 1 and pass 2.  A difficult to debug
  4181.        error: generally the problem is not caused by the statement
  4182.        which received the error message. The problem is caused by an
  4183.        improper statement before this one, but after any other labels
  4184.        (otherwise *they* would have received the error message).
  4185.  
  4186.        When phase errors are discovered, CHASM prints this message,
  4187.        then resynchronizes the location counter to match the offset
  4188.        calculated on pass one.  If further phase errors are reported,
  4189.        the line responsable for each subsequent error will be located
  4190.        between two Phase Error messages, but after any unflagged
  4191.        labels.
  4192.  
  4193.        There are four documented ways to generate phase errors.
  4194.  
  4195.        1. A previous instruction used a symbolic immediate operand
  4196.           prior to the symbol's definition.
  4197.  
  4198.        2. A previous instruction made improper use of a forward
  4199.           referenced label, either an attempt to branch into a data
  4200.           area, or to access a code area as if it was data.
  4201.  
  4202.        3. The label on the flagged statement is defined more than
  4203.           once in the program.
  4204.  
  4205.        4. A previous instruction invoked a macro prior to its
  4206.           definition.
  4207.  
  4208.  
  4209.  
  4210.  
  4211.  
  4212.  
  4213.  
  4214.  
  4215.  
  4216.  
  4217.  
  4218.  
  4219.  
  4220.  
  4221.  
  4222.  
  4223.  
  4224.  
  4225.                                                                    62
  4226.  
  4227.  
  4228.        Whitman Software would appreciate hearing about any other
  4229.        situations which cause the Phase Error message to appear.
  4230.  
  4231.     Parameter Too Large for Expansion: Diagnostic. Replacement of the
  4232.        dummy parameter would cause the macro line to exceed CHASM's
  4233.        internal 255 character limit for manipulating strings.
  4234.        Generally this message will be accompanied by the "Source Line
  4235.        Truncated" message, warning that a line has exceeded the
  4236.        allowed 80 columns.
  4237.  
  4238.     Procedures Nested Too Deeply: Procedures may be
  4239.        nested no more than 10 deep.
  4240.  
  4241.     Source Line Truncated:  The length of the input line exceeded 80
  4242.        characters.
  4243.  
  4244.     Specify Word or Byte Operation: Diagnostic.  CHASM suggests that
  4245.        the Syntax Error might be resolved by adding the suffix "B" or
  4246.        "W" to the instruction mnemonic.  Most, but not all, ambiguous
  4247.        memory references are flagged with this diagnostic.
  4248.  
  4249.     Syntax Error: (OP) (DEST), (SOURCE).  CHASM was unable to find a
  4250.       version of the instruction (OP) which allows the operands
  4251.       (DEST) and (SOURCE).  Either the instruction doesn't exist, or
  4252.       it is an inappropriate choice for the given operands.  The (OP)
  4253.       (Dest), (Source) is a reconstruction of your source line based
  4254.       on how CHASM parsed it.  A comparison of the reconstruction and
  4255.       your original source code will sometimes help pinpoint the
  4256.       error.
  4257.  
  4258.       Syntax Error messages are followed by two diagnostics which
  4259.       spell out in words CHASM's best guess about the operands.
  4260.       Again, a comparison between CHASM's guesses and what you
  4261.       really meant can help find the problem.
  4262.  
  4263.     Too Far For Short Jump: The displacement to the specified label
  4264.        is not in the range -128 to +127.
  4265.  
  4266.     Undefined Operand for EQU: Any operands on an EQU statement must
  4267.        have been previously defined.
  4268.  
  4269.     Undefined Symbol XXX: The symbol XXX was used as an operand, but
  4270.        never appeared as a label, and is not a predefined symbol.
  4271.  
  4272.  
  4273.  
  4274.  
  4275.  
  4276.  
  4277.  
  4278.  
  4279.  
  4280.  
  4281.  
  4282.  
  4283.  
  4284.  
  4285.  
  4286.  
  4287.  
  4288.  
  4289.  
  4290.  
  4291.                                                                    63
  4292.  
  4293.     Unrecognized Operand XXX: XXX is used in the DB or DW operand
  4294.        list, but is not a valid immediate operand. (or string, in the
  4295.        case of DB).
  4296.  
  4297.  
  4298.  
  4299.  
  4300.  
  4301.  
  4302.  
  4303.  
  4304.  
  4305.  
  4306.  
  4307.  
  4308.  
  4309.  
  4310.  
  4311.  
  4312.  
  4313.  
  4314.  
  4315.  
  4316.  
  4317.  
  4318.  
  4319.  
  4320.  
  4321.  
  4322.  
  4323.  
  4324.  
  4325.  
  4326.  
  4327.  
  4328.  
  4329.  
  4330.  
  4331.  
  4332.  
  4333.  
  4334.  
  4335.  
  4336.  
  4337.  
  4338.  
  4339.  
  4340.  
  4341.  
  4342.  
  4343.  
  4344.  
  4345.  
  4346.  
  4347.  
  4348.  
  4349.  
  4350.  
  4351.  
  4352.  
  4353.  
  4354.  
  4355.  
  4356.  
  4357.                                                                    64
  4358.  
  4359.     >>Execution of Assembled Programs<<
  4360.  
  4361.     A. Object code format
  4362.  
  4363.        The object code file produced by CHASM is in the form of a
  4364.        memory image, exactly as will be present in your computer at
  4365.        run time.  No link step is required.  Provided that the segment
  4366.        registers are set correctly, the architecture of the 8088
  4367.        guarantees that code is self-relocating, and will run correctly
  4368.        loaded anywhere in memory.  Storing a program as an exact image
  4369.        of memory at run time is called the COM format by IBM.
  4370.  
  4371.        This COM format is *not* that produced by the IBM assembler.
  4372.        The output of the IBM assembler is in the form of an "object
  4373.        module" suitable for input to the linker.  The object module
  4374.        is not directly executable, but must first be "filtered"
  4375.        through the linker.  This adds an extra step to the process of
  4376.        producing a working program, but gives you the option of
  4377.        combining multiple object modules into one program.  The
  4378.        resulting linked program is *still* not a memory image, but
  4379.        has a header which is used to perform relocation during
  4380.        loading.  This linked program plus header is called the EXE
  4381.        format by IBM.
  4382.  
  4383.     B. Running Assembled Programs From DOS
  4384.  
  4385.        DOS provides a loader for running machine language programs.
  4386.        To run a program, you merely type its name, without the
  4387.        extension.  This is what you're doing every time you use a DOS
  4388.        external command such as FORMAT or CHKDSK.  In fact, the COM
  4389.        format is named after "external COMmand".
  4390.  
  4391.        When DOS loads a program, it examines the file extension to
  4392.        determine what format the file is in, either COM or EXE.  This
  4393.        is why CHASM defaults to using the extension .COM for your
  4394.        object file.  If you plan to run the program from DOS, don't
  4395.        change the extension.
  4396.  
  4397.        For COM programs, DOS builds a 255 byte long "program segment
  4398.        prefix" and sets the segment registers to point to this PSP.
  4399.        The contents of the file are then loaded verbatim right after
  4400.        the PSP, at offset hex 100 in the segment defined by the
  4401.        segment registers.  As soon as loading is complete, your
  4402.        program is executed starting with the instruction at hex 100.
  4403.  
  4404.  
  4405.  
  4406.  
  4407.  
  4408.  
  4409.  
  4410.  
  4411.  
  4412.  
  4413.  
  4414.  
  4415.  
  4416.  
  4417.  
  4418.  
  4419.  
  4420.  
  4421.  
  4422.  
  4423.                                                                    65
  4424.  
  4425.        Although you can totally ignore the PSP, you should read pages
  4426.        E-3 through E-11 of the DOS manual to see what DOS puts there
  4427.        for you.  It turns out there are some real goodies which your
  4428.        program might want to use.
  4429.  
  4430.        When your program is done, it must transfer control back to
  4431.        DOS, otherwise the 8088 will continue to fetch what it
  4432.        believes are instructions from whatever garbage or bit-hash
  4433.        happens to follow your program in memory.  The easiest way to
  4434.        return to DOS is to execute the instruction:
  4435.  
  4436.          INT 20H
  4437.  
  4438.        This is the vectored interrupt reserved by DOS for program
  4439.        termination.
  4440.  
  4441.        While we're on the topic of vectored interrupts, you would be
  4442.        well rewarded to study both the DOS Technical Reference and
  4443.        Hardware Technical Reference Manuals to find out what happens
  4444.        when you execute some of the other interrupts.  Some very
  4445.        useful functions, such as file handling and screen i/o, are
  4446.        available at the machine language level through this
  4447.        mechanism.  Information on interrupts is also available in
  4448.        Peter Norton's book "Programmer's Guide to the IBM PC", which
  4449.        is cheaper than buying both of IBM's reference manuals, and
  4450.        also more readable.
  4451.  
  4452.        Looking at things the other way, by changing the interrupt
  4453.        vector for a given function to point to your own code, you can
  4454.        override the way DOS or the BIOS does something, and do it
  4455.        your way.  DOS even provides a method (via interrupt 27H) by
  4456.        which your new code can be grafted onto DOS, and not be
  4457.        overwritten by other programs.
  4458.  
  4459.     C. Debugging Assembled Programs
  4460.  
  4461.        IBM provides an excellent utility with DOS, called DEBUG.COM.
  4462.        By specifying your program's name as a parameter when invoking
  4463.        DEBUG, you can observe your program execute with DEBUG's trace
  4464.        and other functions.  To debug your program, from DOS type:
  4465.  
  4466.           DEBUG progname.COM
  4467.  
  4468.  
  4469.  
  4470.  
  4471.  
  4472.  
  4473.  
  4474.  
  4475.  
  4476.  
  4477.  
  4478.  
  4479.  
  4480.  
  4481.  
  4482.  
  4483.  
  4484.  
  4485.  
  4486.  
  4487.  
  4488.  
  4489.                                                                    66
  4490.  
  4491.        DEBUG builds a PSP and loads your program just like DOS does,
  4492.        but you have the added power of the debugging commands to
  4493.        monitor your program while it runs.  See chapter 6 of the DOS
  4494.        manual for more details about using DEBUG.
  4495.  
  4496.        On the topic of debugging, I can recommend most highly a
  4497.        program called TRACE86, from Morgan Computing (10400 N.
  4498.        Central Expressway, Suite 210, Dallas, TX 75231).  The program
  4499.        replaces DEBUG, and although rather steeply priced, makes the
  4500.        IBM debugger look silly.  I've been using TRACE86 for some
  4501.        time now, and wouldn't be without it.
  4502.  
  4503.     D. Using Assembled Programs in BASIC
  4504.  
  4505.        To incorporate a machine language subroutine in a BASIC
  4506.        program, write it in assembly language, then assemble it with
  4507.        CHASM.  You should read page C-7 of the BASIC manual for some
  4508.        conventions to use in writing your subroutine.  In particular,
  4509.        note that you must declare the routine to CHASM as a FAR
  4510.        procedure using the PROC pseudo-op, and that the last
  4511.        instruction of the routine should be a RET.
  4512.  
  4513.        Unlike programs which are run directly from DOS, your routine
  4514.        will not be preceded by a program segment prefix.  You should
  4515.        prevent CHASM from leaving room for a PSP by putting an ORG 0
  4516.        pseudo-op at the beginning of your routine. If you don't
  4517.        include the ORG, memory references will not be assembled
  4518.        correctly.  Example:
  4519.  
  4520.             ORG  0    ;no psp
  4521.        SUBR PROC FAR  ;far procedure
  4522.             ...       ;body of subroutine
  4523.             RET
  4524.             ENDP
  4525.  
  4526.        CHASM supports two methods for getting assembled routines into
  4527.        BASIC programs.  The methods differ in whether the routine is
  4528.        included in the BASIC program file, or in a separate file.
  4529.  
  4530.        A utility program called COM2DATA is provided for including
  4531.        machine language within BASIC program files.  The program is
  4532.        distributed in source code form (file COM2DATA.ASM) and must
  4533.        be assembled with CHASM prior to use.  The program functions
  4534.        as a DOS 2 filter, reading a COM file in from the standard
  4535.        input, and writing a series of BASIC DATA statements to the
  4536.        standard output.
  4537.  
  4538.  
  4539.  
  4540.  
  4541.  
  4542.  
  4543.  
  4544.  
  4545.  
  4546.  
  4547.  
  4548.  
  4549.  
  4550.  
  4551.  
  4552.  
  4553.  
  4554.  
  4555.                                                                    67
  4556.  
  4557.  
  4558.        COM2DATA's syntax is as follows:
  4559.  
  4560.          COM2DATA [<infile] [>outfile] [linenum]
  4561.  
  4562.        You specify the input and output files as with any DOS 2
  4563.        filter.  The linenum parameter sets the starting line number
  4564.        used on the BASIC code produced.  If you don't specify
  4565.        linenum, it defaults to 1000.
  4566.  
  4567.        If you MERGE the file of DATA statements into your BASIC
  4568.        program, the program can then READ the data and POKE it into
  4569.        memory.  An example program to do this is given on page C-6 of
  4570.        the BASIC manual.  An alternative approach would be to store
  4571.        the routine in a string variable, which could later be located
  4572.        with the VARPTR function. 
  4573.  
  4574.        If you would prefer to keep your machine language subroutine
  4575.        in a separate file, include a BSAVE pseudo-op somewhere within
  4576.        your assembly language source code.  CHASM will build a header
  4577.        on the object code produced, which will mimic that built by
  4578.        BASIC's BSAVE command.  The resulting file may be BLOADed by
  4579.        BASIC to any location in memory.
  4580.  
  4581.        You transfer control to your routine with either the USR
  4582.        function, or the CALL statement.  Syntax for these statements
  4583.        can be found in the BASIC manual.
  4584.  
  4585.  
  4586.  
  4587.  
  4588.  
  4589.  
  4590.  
  4591.  
  4592.  
  4593.  
  4594.  
  4595.  
  4596.  
  4597.  
  4598.  
  4599.  
  4600.  
  4601.  
  4602.  
  4603.  
  4604.  
  4605.  
  4606.  
  4607.  
  4608.  
  4609.  
  4610.  
  4611.  
  4612.  
  4613.  
  4614.  
  4615.  
  4616.  
  4617.  
  4618.  
  4619.  
  4620.  
  4621.                                                                    68
  4622.  
  4623.  
  4624.     E. Using Assembled Programs with Turbo Pascal:
  4625.  
  4626.        CHASM and Turbo Pascal work splendidly together, complementing
  4627.        each other's strong points.  You can use CHASM to provide new
  4628.        functions you wish Turbo had, or to fine tune a critical
  4629.        procedure for optimum speed.   CHASM itself is written in a
  4630.        combination of Turbo Pascal and CHASM.
  4631.  
  4632.        CHASM supports two techniques for producing machine language
  4633.        code for Turbo Pascal: external procedures or functions, and
  4634.        Turbo INLINE code.
  4635.  
  4636.     1. External Procedures and Functions:
  4637.  
  4638.        Turbo loads external procedures and functions within the same
  4639.        segment as the rest of your Pascal program.  You have no
  4640.        control of the exact load location (more on this later), but
  4641.        on the other hand, you don't have to worry about setting aside
  4642.        a special location for your procedures (as in BASIC).  Since
  4643.        your external procedure is loaded in the same segment as the
  4644.        Pascal code, it should be declared NEAR to CHASM:
  4645.  
  4646.          EXTERNAL PROC NEAR
  4647.                   ...           ;body of procedure
  4648.                   ...
  4649.                   ENDP
  4650.  
  4651.        Turbo passes parameters to your procedure/function via the
  4652.        stack.  To work effectively, a good grasp of the stack
  4653.        structure is critical.  Read the Turbo manual for information
  4654.        on internal data formats and parameter passing, to see just
  4655.        what to expect on the stack.  Also, remember that the stack
  4656.        grows down from the top of memory.
  4657.  
  4658.        If you're going to access the stack in your procedure, the
  4659.        first thing you should do is set up BP as a stack pointer.
  4660.        Since Turbo also uses BP, you have to save the current value
  4661.        first.  The obvious place to save it is on the stack...
  4662.  
  4663.           PUSH BP           ;save old BP
  4664.           MOV  BP, SP        ;and set up to indirectly address stack
  4665.  
  4666.  
  4667.  
  4668.  
  4669.  
  4670.  
  4671.  
  4672.  
  4673.  
  4674.  
  4675.  
  4676.  
  4677.  
  4678.  
  4679.  
  4680.  
  4681.  
  4682.  
  4683.  
  4684.  
  4685.  
  4686.  
  4687.                                                                    69
  4688.  
  4689.        You can now access the parameters on the stack using offsets
  4690.        off the BP register.  Note that since you PUSHed BP,
  4691.        everything is 2 bytes deeper onto the stack than what Turbo
  4692.        originally sent you.
  4693.  
  4694.        Here's an example.  Suppose you declare the following external
  4695.        function in Turbo:
  4696.  
  4697.           function Sum(x,y: int): int;
  4698.              external 'sum.com';
  4699.  
  4700.        After you've pushed BP, here's how the stack looks:
  4701.  
  4702.            stack contents           indirect address
  4703.         ----------------------------------------------
  4704.            <value of parameter y>        6[BP]
  4705.            <value of parameter x>        4[BP]
  4706.            <return address to Turbo>     2[BP]
  4707.            <old BP value>                 [BP]
  4708.  
  4709.        The indirect addresses go up two at a time, since each item on
  4710.        the stack is a word (two bytes) long. You can access the
  4711.        parameters using their indirect addresses. Here's the code for
  4712.        an external function to add two integer parameters:
  4713.  
  4714.        SUM  PROC NEAR
  4715.             PUSH BP          ;save old BP
  4716.             MOV  BP, SP      ;set up stack pointer
  4717.  
  4718.             MOV  AX,  4[BP]  ;get parameter x
  4719.             MOV  ADD, 6[BP]  ;add parameter y
  4720.                              ;leave sum in AX to return to Turbo
  4721.  
  4722.             POP  BP          ;restore old BP for Turbo
  4723.             RET  4           ;clear params off stack
  4724.             ENDP
  4725.  
  4726.        A more elegant way to access the parameters is by using a
  4727.        CHASM structure to define their offsets on the stack:
  4728.  
  4729.        STACK    STRUC
  4730.        OLDBP    DW   0000H
  4731.        RETADDR  DW   0000H
  4732.        XPARAM   DW   0000H
  4733.        YPARAM   DW   0000H
  4734.                 ENDSTRUC
  4735.  
  4736.  
  4737.  
  4738.  
  4739.  
  4740.  
  4741.  
  4742.  
  4743.  
  4744.  
  4745.  
  4746.  
  4747.  
  4748.  
  4749.  
  4750.  
  4751.  
  4752.  
  4753.                                                                    70
  4754.  
  4755.  
  4756.        With this structure added to the above example, you could
  4757.        access the parameters like this:
  4758.  
  4759.                 MOV  AX, XPARAM[BP]    ;get parameter X
  4760.  
  4761.        Functions return scalar results by having the value in AX upon
  4762.        return.  The function in the above example saves some time by
  4763.        calculating the value in AX in the first place.  Upon exit,
  4764.        the function POPs BP, to restore the value Turbo was using.
  4765.  
  4766.        Note the RET 4 in the example.  This returns to Turbo, while
  4767.        simultaneously POPing (and discarding) 4 bytes off the stack.
  4768.        This clears off the two parameters which Turbo passed.  If
  4769.        there were three parameters, you'd use a RET 6; if none, a
  4770.        simple RET would do. When Turbo receives control, it assumes
  4771.        that you've cleaned up the stack by removing all parameters.
  4772.        If you don't do this properly, a run-time error, or even a
  4773.        system crash will result.
  4774.  
  4775.        (Typical scenario:  Turbo tries to return from one of its own
  4776.        subroutines, thinking the top of the stack has the return
  4777.        address.  Unfortunately, the top is really an integer
  4778.        parameter, left over from your external function.  Turbo's
  4779.        RET sends control into some random area of memory, and boom -
  4780.        the system crashes.)
  4781.  
  4782.        It's easy to get confused about the exact contents of the
  4783.        stack.  If your procedure doesn't seem to be working right,
  4784.        the first thing to suspect is Turbo and you have different
  4785.        ideas about what's where on the stack.  A DEBUG session can
  4786.        usually straighten things out.
  4787.  
  4788.        Boolean functions constitute a special case which is poorly
  4789.        documented in the Turbo Pascal manual.  Boolean functions must
  4790.        return their result in two ways:
  4791.  
  4792.            1. by setting the zero flag (Z = false, NZ = true)
  4793.  
  4794.            2. and by returning either 0 (false) or 1 (true) in AX
  4795.  
  4796.        The first return method is assumed by Turbo if you use the
  4797.        function in a conditional statement, the second if you assign
  4798.        the value of the function to a variable.  You need to return
  4799.        the result both ways to cover all possible uses of your
  4800.        function.
  4801.  
  4802.  
  4803.  
  4804.  
  4805.  
  4806.  
  4807.  
  4808.  
  4809.  
  4810.  
  4811.  
  4812.  
  4813.  
  4814.  
  4815.  
  4816.  
  4817.  
  4818.  
  4819.                                                                    71
  4820.  
  4821.  
  4822.        When external functions are called, in addition to the normal
  4823.        parameters, Turbo passes something called the  "function
  4824.        result" on the stack.  When the result is a scalar type, this
  4825.        seems to be intended just as a local work area for you to use,
  4826.        since Turbo ignores any value you store there.  Like a
  4827.        parameter, the function result must be POPed off the stack
  4828.        when your return to Turbo. Unlike scalar parameters (which
  4829.        always occupy a word of stack memory, even if they are defined
  4830.        as byte), the function result is the exact length of the
  4831.        result type.  Thus for a boolean function, you have to POP off
  4832.        one extra byte above and beyond those for clearing off the
  4833.        parameters.
  4834.  
  4835.        A problem of addressability can crop up if your external
  4836.        procedure tries to maintain its own local variables and/or
  4837.        constants.  The problem is that you have no way of knowing
  4838.        just where Turbo is going to load your procedure within the
  4839.        shared segment.  As such, the address CHASM calculates for any
  4840.        memory locations are going to be offset from their real values
  4841.        by some unknown constant, the offset of the procedure within
  4842.        the shared segment.  This is called a relocation problem.
  4843.  
  4844.        Fortunately, there's a way around this problem, but it
  4845.        requires using a trick.  Your program has to figure out, *at
  4846.        run time*, just where it's located in memory.  If you could
  4847.        find out the offset of any known point in your procedure,
  4848.        you'd "have your bearings" so to speak, and could go on.
  4849.  
  4850.        The trick is as follows.  The 8088 CALL instruction pushes the
  4851.        address of the next instruction onto the stack, then branches
  4852.        to the location given in the CALL.  By performing a dummy
  4853.        CALL, then stealing the value off the stack, we have the
  4854.        location of a known spot in the procedure.   By subtracting
  4855.        the offset within the procedure of that known location, we get
  4856.        a pointer to the beginning of the procedure which can be used
  4857.        to access everything else.  Here's an example:
  4858.  
  4859.  
  4860.  
  4861.  
  4862.  
  4863.  
  4864.  
  4865.  
  4866.  
  4867.  
  4868.  
  4869.  
  4870.  
  4871.  
  4872.  
  4873.  
  4874.  
  4875.  
  4876.  
  4877.  
  4878.  
  4879.  
  4880.  
  4881.  
  4882.  
  4883.  
  4884.  
  4885.                                                                    72
  4886.  
  4887.        LOCAL  PROC NEAR
  4888.               PUSH BP                     ;set up to access stack
  4889.               MOV  BP, SP                 ; ditto
  4890.  
  4891.               CALL DUMMY                  ;establish addressability
  4892.        DUMMY  POP  BX                     ;  "           "
  4893.               SUB  BX, OFFSET(DUMMY)
  4894.  
  4895.               MOV  AX, 4[BP]                ;get parameter
  4896.               SEG  CS                       ;offset relative to CS
  4897.               ADD  OFFSET(TOTAL)[BX], AX    ;maintain running total
  4898.  
  4899.               POP  BP
  4900.               RET  2
  4901.        TOTAL  DW   0000H
  4902.               ENDP
  4903.  
  4904.        We use indirect addressing here.  After the funny business
  4905.        with the CALL, POP, SUB sequence, BX has a pointer to the
  4906.        beginning of the procedure.  Using indirect addressing, we
  4907.        take that pointer and add in the offset of the memory location
  4908.        we want to access.  In this example we're using a local
  4909.        variable to maintain a running total of the parameter which
  4910.        gets passed.
  4911.  
  4912.        Note the SEG CS just before the ADD which accesses the
  4913.        location TOTAL.  Since we found our bearings by stealing the
  4914.        address of a program instruction, our offset is known relative
  4915.        to the CS register, NOT the DS which is normally used to
  4916.        access data.  The SEG CS forces the 8088 to calculate the
  4917.        address using CS rather than the default DS register.  Every
  4918.        time you access a memory location within your procedure, you
  4919.        *MUST* do it relative to CS by using a segment override.
  4920.  
  4921.        Turbo requires that you preserve the values of the following
  4922.        registers:
  4923.  
  4924.             BP, CS, DS, SS
  4925.  
  4926.        If you want to use these registers in your routine, the
  4927.        easiest way to preserve them is to PUSH them onto the stack at
  4928.        the beginning of your routine, then POP them just before
  4929.        returning.  As near as I can tell, you can safely trash the
  4930.        other registers.
  4931.  
  4932.  
  4933.  
  4934.  
  4935.  
  4936.  
  4937.  
  4938.  
  4939.  
  4940.  
  4941.  
  4942.  
  4943.  
  4944.  
  4945.  
  4946.  
  4947.  
  4948.  
  4949.  
  4950.  
  4951.                                                                    73
  4952.  
  4953.     2. INLINE Code
  4954.  
  4955.        An alternative method of incorporating code into Turbo Pascal
  4956.        is through Turbo's inline statement.  The inline statement is
  4957.        intended for short routines or patches where you just give
  4958.        Turbo a list of numbers representing the code.  In addition to
  4959.        numbers, you can also include variable names in the inline
  4960.        list.  Turbo replaces them with their offsets at compile time.
  4961.  
  4962.        CHASM's INLINE pseudo-op is provided to facilitate producing
  4963.        Turbo inline code.  If you put an INLINE pseudo-op in your
  4964.        CHASM source file, rather than producing a normal object code
  4965.        file, CHASM produces a text file formatted to include in a
  4966.        Turbo inline statement.  For example:
  4967.  
  4968.            inline        ;shift to inline mode
  4969.            mov  ah, 0FH  ;call bios for video mode
  4970.            int  10H      ;  ditto
  4971.  
  4972.        produces the following object file:
  4973.  
  4974.                         {    inline       ;shift to inline mode    }
  4975.           $B4/$0F/      {    mov ah, 0FH  ;call bios for video mode}
  4976.           $CD/$10/      {    int 10H      ;  ditto                 }
  4977.  
  4978.        Object code is output in text form, as hex constants.  A
  4979.        comment with the source code for each line is also generated.
  4980.  
  4981.        The INLINE pseudo-op can appear anywhere in your source file,
  4982.        and it requires no operands.
  4983.  
  4984.        Object files produced from source files with an INLINE 
  4985.        pseudo-op are NOT executable!  They contain text suitable for
  4986.        inclusion in Turbo Pascal inline statements.  It's probably a
  4987.        good idea to override CHASM's default name for the object
  4988.        file, and specify something with an extension other than COM
  4989.        to prevent DOS from trying to run the program.
  4990.  
  4991.        Your inline code must preserve the BP, SP, DS and SS
  4992.        registers. If you need to modify these registers, you should
  4993.        PUSH the ones you need at the beginning of your code, and POP
  4994.        them at the end.
  4995.  
  4996.  
  4997.  
  4998.  
  4999.  
  5000.  
  5001.  
  5002.  
  5003.  
  5004.  
  5005.  
  5006.  
  5007.  
  5008.  
  5009.  
  5010.  
  5011.  
  5012.  
  5013.  
  5014.  
  5015.  
  5016.  
  5017.                                                                    74
  5018.  
  5019.        Turbo's inline statement allows you to insert variable names
  5020.        in with the list of numbers.  At compile time, Turbo will
  5021.        replace the name with the 16 bit offset of the variable in its
  5022.        native segment.  (See the Turbo Pascal manual for a discussion
  5023.        of internal data formats and the native segment of variables.)
  5024.  
  5025.        CHASM supports this capability with the TURBO() function.
  5026.        CHASM treats TURBO() as 16 bit immediate data during assembly.
  5027.        However, in place of the two bytes of data, CHASM outputs the
  5028.        function argument literally for Turbo to evaluate:
  5029.  
  5030.           inline
  5031.           mov   bl, turbo(flag)[bp]     ;local variable "flag"
  5032.           mov   ax, cs:[turbo(maxcode)] ;typed constant "maxcode"
  5033.           lds   si, turbo(y)[bp]        ;pointer to var parameter "y"
  5034.  
  5035.        produces:
  5036.  
  5037.                               {      inline                        }
  5038.           $8A/$9E/FLAG/       {      mov   bx, turbo(flag)[bp]     }
  5039.           $2E/$A1/MAXCODE/    {      mov   ax, cs:[turbo(maxcode)] }
  5040.           $C5/$B6/Y/          {      lds   si, turbo(y)[bp]        }
  5041.  
  5042.  
  5043.  
  5044.  
  5045.  
  5046.  
  5047.  
  5048.  
  5049.  
  5050.  
  5051.  
  5052.  
  5053.  
  5054.  
  5055.  
  5056.  
  5057.  
  5058.  
  5059.  
  5060.  
  5061.  
  5062.  
  5063.  
  5064.  
  5065.  
  5066.  
  5067.  
  5068.  
  5069.  
  5070.  
  5071.  
  5072.  
  5073.  
  5074.  
  5075.  
  5076.  
  5077.  
  5078.  
  5079.  
  5080.  
  5081.  
  5082.  
  5083.                                                                    75
  5084.  
  5085.     >>Notes for Those Upgrading to This Version of CHASM<<
  5086.  
  5087.     CHASM is not yet carved in stone - improvements and corrections
  5088.     are made fairly frequently, based on both my own experience in
  5089.     using the program, and the comments of outside users.  This
  5090.     section summarizes the changes which have been made since version
  5091.     1.2 was released.  Changes followed with an asterisk (*) denote
  5092.     modifications which could invalidate programs written under
  5093.     earlier versions of CHASM.
  5094.  
  5095.     Version   Notes
  5096.  
  5097.     4.07      Speed enhancement.  Intersegment JMP and CALL fixed.
  5098.               Expressions now allowed in the subset.  Characters + -
  5099.               * / ) ( are now reserved for expressions only. (*)
  5100.  
  5101.     4.06      Speed enhancement.  Turbo Pascal INLINE facility.
  5102.               /VIDEO configuration switch.  New conditionals: IFREG,
  5103.               IFREG8, IFREG16, IFSEGREG.  New pseudo-ops: INLINE,
  5104.               RADIX, CHKJMP, NOCHKJMP.  New function: TURBO(). Single
  5105.               quotes now allowed in strings (use two).  Obsolete
  5106.               COUNT, ENDC and DM pseudo-ops no longer supported. (*)
  5107.  
  5108.     4.05      Speed enhancement.  Characters now work in expressions.
  5109.               EJECT and EJECTIF appear *before* page breaks.  /DPAGE
  5110.               configuration switch.  Parameter collection on macro
  5111.               invocations now halts before comments.  SHL can now
  5112.               also be written as SAL.
  5113.  
  5114.     4.04      RET with displacement is now assembled correctly.
  5115.               Parser bug fixed which crashed on strings with '/'.
  5116.  
  5117.     4.03      Assembler variables.  Operand size incompatibility now
  5118.               reported. FSUB now assembles correctly.  Intermittent
  5119.               bug in expressions with forward references fixed.
  5120.               Indirect memory references with offsets and segment
  5121.               overides now assemble correctly.  Only the first
  5122.               occurrence of a phase error is now reported.
  5123.  
  5124.     4.02      DS storage assembly is now turned off during structure
  5125.               definitions.  Structures assemble faster. Intermittent
  5126.               problem with macro parameter expansion cleared up.
  5127.  
  5128.     4.01      8087 support.  WAITON and WAITOFF pseudo-ops. Internal
  5129.               labels for macros.  Corrects bug which caused crash on
  5130.               certain syntax errors.
  5131.  
  5132.  
  5133.  
  5134.  
  5135.  
  5136.  
  5137.  
  5138.  
  5139.  
  5140.  
  5141.  
  5142.  
  5143.  
  5144.  
  5145.  
  5146.  
  5147.  
  5148.  
  5149.                                                                    76
  5150.  
  5151.  
  5152.     4.00      Total rewrite in Turbo Pascal.  Subset replaces
  5153.               interpreted version as free distribution release.
  5154.               Faster assembly.  Symbol and macro tables now use all
  5155.               available memory.  Nested macros permitted.  Operand
  5156.               expressions. $ now returns location counter value.  New
  5157.               syntax for segment overrides.  Conditional pseudo-ops
  5158.               now evaluate operands.  Improved error and diagnostic
  5159.               messages.  DOS 2 or later now required (*). DOS 2 path
  5160.               support for files. Setting of DOS 2 ERRORLEVEL. EJECTIF
  5161.               pseudo-op added. New configuration switches: /DWIDTH,
  5162.               /FF /TIMER, /PATH. CHASM.CFG must now have only one
  5163.               switch per line (*).
  5164.  
  5165.     3.15      Macros added. New pseudo-ops: MACRO, ENDM, IFE, IFNE,
  5166.               IFB, IFNB, ELSE, ENDIF.
  5167.  
  5168.     3.14      Interpreted version frozen at version 2.13, further
  5169.               changes apply only to compiled version.  Memory
  5170.               requirement raised to 128K.  INCLUDE, STRUC, ENDSTRUC,
  5171.               DM, DW, LIST, NOLIST, COUNT and ENDC pseudo-ops added.
  5172.               Alternate mnemonics for the jump on condition
  5173.               instructions, and alternate syntax for the DIV and MUL
  5174.               instructions.  Binary numbers added.
  5175.  
  5176.     2.13      Assembly can now be aborted with the Esc key. Negative
  5177.               decimal numbers are working again.  Input lines now
  5178.               limited to 80 characters, and labels must begin with a
  5179.               non-numeral. (*)
  5180.  
  5181.     2.12      Listings can now be suppressed.  Error messages echoed to
  5182.               the console on non-screen listings. Expert mode added.
  5183.  
  5184.     2.11      Pagination improved.  Listings now time stamped. OFFSETs
  5185.               and word values now allowed in DB operand list.
  5186.  
  5187.     2.10      Equated symbols allowed in the DB operand list.  Status
  5188.               line improved.
  5189.  
  5190.     2.09      The first digit of hexadecimal constants must now be in
  5191.               the range 0-9. A leading zero is permitted on four digit
  5192.               hex constants, to allow fulfilling this condition. (*)
  5193.  
  5194.     2.08      Configuration process expanded.  CHASM now skips over
  5195.               perforations on printed listings.  EJECT pseudo-op added.
  5196.  
  5197.  
  5198.  
  5199.  
  5200.  
  5201.  
  5202.  
  5203.  
  5204.  
  5205.  
  5206.  
  5207.  
  5208.  
  5209.  
  5210.  
  5211.  
  5212.  
  5213.  
  5214.  
  5215.                                                                    77
  5216.  
  5217.     2.07      Oops.  Configuration file now works as advertised.
  5218.  
  5219.     2.06      CHASM now supports reverse long jumps.
  5220.  
  5221.     2.05      Compiled version released.  BSAVE pseudo-op.
  5222.               Configuration process simplified.
  5223.  
  5224.     2.04      TABs are now expanded and replaced with blanks, for
  5225.               compatibility with IBM text editors.
  5226.  
  5227.     2.03      Two bugs corrected.  The first involved incorrect
  5228.               assembly of indirect memory references with
  5229.               displacements in the range 128-255.  The second caused
  5230.               a crash if a hex number longer than 4 digits used.
  5231.  
  5232.     2.01      COM2DATA utility added.
  5233.  
  5234.     2.00      Corrected a bug in the DS and DB pseudo-ops which caused
  5235.               the last label in a program to be redefined as a memory
  5236.               location.  Also, the TAB character was added as a new
  5237.               delimiter, and PRIMER.DOC was added to the CHASM package.
  5238.  
  5239.     1.9       The short jump is now represented with mnemonic JMPS, for
  5240.               compatibility with DEBUG version 1.1. (*)
  5241.  
  5242.     1.8       The operand type "character" was added as a new way to
  5243.               represent immediate data.
  5244.  
  5245.     1.7       The DS operator now works for blocks larger than 255
  5246.               bytes.  Also, the OFFSET function now works properly in
  5247.               the displacement field of an indirect memory reference.
  5248.  
  5249.     1.6       A revision of this document.  Some sections were improved
  5250.               slightly, and in response to user requests, a section on
  5251.               execution of assembled programs was added.
  5252.  
  5253.     1.5       Corrected an error which generated the message "Data too
  5254.               Long" if the value FFH was used as 8 bit immediate data.
  5255.  
  5256.     1.4       User interface improved.  CHASM now traps some common
  5257.               input errors such as misspelling a file name, or
  5258.               forgetting to turn on your printer.
  5259.  
  5260.     1.3       A speed enhancement.  Version 1.3 benchmarks about 5
  5261.               times faster than version 1.2.
  5262.  
  5263.  
  5264.  
  5265.  
  5266.  
  5267.  
  5268.  
  5269.  
  5270.  
  5271.  
  5272.  
  5273.  
  5274.  
  5275.  
  5276.  
  5277.  
  5278.  
  5279.  
  5280.  
  5281.                                                                    78
  5282.  
  5283.     >>Miscellaneous and A Word From Our Sponsor...<<
  5284.  
  5285.     A. Programming Notes:
  5286.  
  5287.        1. CHASM is written in a combination of Turbo Pascal and
  5288.           CHASM.  This is less incestuous than it sounds: the
  5289.           program was written in Turbo, then profiled to single
  5290.           out the critical routines.   The rate determining sections
  5291.           were rewritten in optimized assembly language, and
  5292.           assembled with the original Turbo Pascal version of CHASM.
  5293.           These routines were then incorporated as Turbo external
  5294.           procedures and functions in a new version of CHASM.
  5295.  
  5296.           The speed enhancements possible by "helping out" Turbo with
  5297.           CHASM can be quite dramatic.  Replacing four rate limiting
  5298.           routines out of the over two hundred routines in CHASM gave
  5299.           almost a four-fold speed increase!
  5300.  
  5301.           CHASM's source code is available to registered users by
  5302.           sending a formatted disk and stamped return mailer.  If you
  5303.           make any improvements, I'd like to hear about them for
  5304.           possible inclusion in future releases.
  5305.  
  5306.           Please note that although you can modify CHASM for your own
  5307.           use, under NO CIRCUMSTANCES may you distribute modified or
  5308.           translated versions, either in the public domain or for
  5309.           profit.
  5310.  
  5311.     B. Red Tape and Legal Nonsense:
  5312.  
  5313.        1. Disclaimer:
  5314.  
  5315.           CHASM is distributed as is, with no guarantee that it will
  5316.           work correctly in all situations.  In no event will the
  5317.           Author be liable for any damages, including lost profits,
  5318.           lost savings or other incidental or consequential damages
  5319.           arising out of the use of or inability to use these programs,
  5320.           even if the Author has been advised of the possibility of
  5321.           such damages, or for any claim by any other party.
  5322.  
  5323.           Despite the somewhat imposing statement above, it *is* my
  5324.           intention to fix any bugs which are brought to my attention.
  5325.           See the appendix on Bug Reporting for more details.
  5326.  
  5327.  
  5328.  
  5329.  
  5330.  
  5331.  
  5332.  
  5333.  
  5334.  
  5335.  
  5336.  
  5337.  
  5338.  
  5339.  
  5340.  
  5341.  
  5342.  
  5343.  
  5344.  
  5345.  
  5346.  
  5347.                                                                    79
  5348.  
  5349.        2. Copyright Information:
  5350.  
  5351.           The entire CHASM distribution package, consisting of the
  5352.           main program, documentation files, and various data and
  5353.           utility files, is copyright (c) 1983, 1984, 1985 and 1986
  5354.           by David Whitman.  The author reserves the exclusive right
  5355.           to distribute this package, or any part thereof, for
  5356.           profit. The name "CHASM (tm)", applied to a microcomputer
  5357.           assembler program, is a trademark of David Whitman.
  5358.  
  5359.           CHASM's Subset version and various subsidiary files may be
  5360.           copied freely by individuals for evaluation purposes.  It
  5361.           is expected that those who find the package useful will
  5362.           make a contribution directly to the author of the program.
  5363.           The Subset version identifies itself by displaying a banner
  5364.           page giving the author's address and inviting free copying.
  5365.           ONLY VERSIONS DISPLAYING THIS BANNER PAGE MAY BE COPIED.
  5366.  
  5367.           CHASM's Advanced version is only available to registered
  5368.           users who have made the $40 suggested payment.  Registered
  5369.           users may copy the program for backup purposes, but must
  5370.           restrict use of the program to either one user or one CPU,
  5371.           at their option.
  5372.  
  5373.           CHASM's source code is made available for educational
  5374.           purposes and to allow users to customize for their own
  5375.           personal use.  Under NO CIRCUMSTANCES may modified versions
  5376.           or translations into other computer languages be
  5377.           distributed, either in the public domain or for profit.
  5378.  
  5379.           User groups and clubs are authorized to distribute CHASM's
  5380.           Subset version under the following conditions:
  5381.  
  5382.           1.  No charge is made for the software or documentation.  A
  5383.               nominal distribution fee may be charged, provided that
  5384.               it is no more than $8 total.
  5385.  
  5386.           2.  Recipients are to be informed of the user-supported
  5387.               software concept, and encouraged to support it with
  5388.               their donations.
  5389.  
  5390.           3.  The program and documentation are not modified in ANY
  5391.               way, and are distributed together.
  5392.  
  5393.  
  5394.  
  5395.  
  5396.  
  5397.  
  5398.  
  5399.  
  5400.  
  5401.  
  5402.  
  5403.  
  5404.  
  5405.  
  5406.  
  5407.  
  5408.  
  5409.  
  5410.  
  5411.  
  5412.  
  5413.                                                                    80
  5414.  
  5415.           Interested manufacturers are invited to contact Whitman
  5416.           Software to discuss licensing CHASM for bundling with
  5417.           MS-DOS based computer systems. 
  5418.  
  5419.           Distribution of CHASM outside the United States is through
  5420.           licensed distributors, on a royalty basis.  Interested
  5421.           distributors are invited to contact Whitman Software. 
  5422.  
  5423.        3. Royalty Information: 
  5424.  
  5425.           No royalties are required to distribute programs produced
  5426.           using CHASM.  However, if you send me a copy of any major
  5427.           program you have produced using CHASM, I'll give you a free
  5428.           page of advertising in this document. 
  5429.  
  5430.        4. Educational Discount:
  5431.  
  5432.           Substantial discounts are available for multi-CPU licenses
  5433.           of CHASM's Advanced version to educational institutions.
  5434.           Contact Whitman Software for details.
  5435.  
  5436.     C. An Offer You Can't Refuse. 
  5437.  
  5438.        CHASM is User-Supported software, distributed under a
  5439.        modification of the FREEWARE (tm) marketing scheme developed by
  5440.        the late Andrew Fluegelman, whose inspiration and efforts are
  5441.        gratefully acknowledged.
  5442.  
  5443.        Anyone may obtain a free copy of CHASM's Subset version by
  5444.        sending a blank, formatted diskette to the author. An
  5445.        addressed, postage-paid return mailer must accompany the disk
  5446.        (no exceptions, please). 
  5447.  
  5448.        A copy of the program, with documentation, will be sent by
  5449.        return mail.  The program will carry a notice suggesting a
  5450.        payment to the program's author.  Making the payment
  5451.        is totally voluntary on the part of the user.  Regardless of
  5452.        whether a payment is made, the user is encouraged to
  5453.        share the program with others.  Payment for use is
  5454.        discretionary on the part of each subsequent user. 
  5455.  
  5456.  
  5457.  
  5458.  
  5459.  
  5460.  
  5461.  
  5462.  
  5463.  
  5464.  
  5465.  
  5466.  
  5467.  
  5468.  
  5469.  
  5470.  
  5471.  
  5472.  
  5473.  
  5474.  
  5475.  
  5476.  
  5477.  
  5478.  
  5479.                                                                    81
  5480.  
  5481.        The underlying philosophy here is based on three principles: 
  5482.  
  5483.        First, that the value and utility of software is best assessed
  5484.           by the user on his/her own system.  Only after using a
  5485.           program can one really determine whether it serves personal
  5486.           applications, needs, and tastes. 
  5487.  
  5488.        Second, that the creation of independent personal computer
  5489.           software can and should be supported by those who benefit
  5490.           from its use.  Remember the Tanstaafl principal:  There
  5491.           Ain't No Such Thing as a Free Lunch.
  5492.  
  5493.        Finally, that copying and networking of programs should be
  5494.           encouraged, rather than restricted.  The ease with which
  5495.           software can be distributed outside traditional commercial
  5496.           channels reflects the strength, rather than the weakness,
  5497.           of electronic information. 
  5498.  
  5499.       If you like this software, please help support it.  Your
  5500.       support can take three forms: 
  5501.  
  5502.       1. Become a registered user.  The suggested payment for
  5503.          registration is $40.
  5504.  
  5505.       2. Suggestions, comments, and bug reports.  Your comments will
  5506.          be taken seriously - user feedback was responsible for most
  5507.          of the changes listed in CHASM's revision history. 
  5508.  
  5509.       3. Spread the word.  Make copies of the Subset for friends.
  5510.          Write the editor of your favorite computer magazine.
  5511.          Astronomical advertising costs are one big reason that
  5512.          commercial software is so overpriced.  To continue offering
  5513.          CHASM this way, I need your help in letting other people
  5514.          know about CHASM. 
  5515.  
  5516.  
  5517.  
  5518.  
  5519.  
  5520.  
  5521.  
  5522.  
  5523.  
  5524.  
  5525.  
  5526.  
  5527.  
  5528.  
  5529.  
  5530.  
  5531.  
  5532.  
  5533.  
  5534.  
  5535.  
  5536.  
  5537.  
  5538.  
  5539.  
  5540.  
  5541.  
  5542.  
  5543.  
  5544.  
  5545.                                                                    82
  5546.  
  5547.       Those who make the $40 payment to become registered users
  5548.       receive the following benefits:
  5549.  
  5550.       1. An upgrade to the Advanced version of the program. The
  5551.          Advanced version executes twice as fast as the Subset and
  5552.          supports macros, conditional assembly and other features.
  5553.          An order form for the Advanced version is given at the end
  5554.          of this manual.
  5555.  
  5556.       2. User support, by phone or mail.  Support is only
  5557.          available to registered users.  Phone numbers and the
  5558.          address for help are given below.
  5559.  
  5560.       3. Notices announcing the release of significant upgrades.
  5561.  
  5562.     CHASM is copyrighted, and users are requested NOT to make copies
  5563.     of the Advanced version other than for their own use.  I am
  5564.     strongly opposed to copy protection, and would regret being
  5565.     forced to protect CHASM.  Please recognize the amount of time and
  5566.     money which went into producing CHASM, and respect the wishes of
  5567.     the author. 
  5568.  
  5569.           David Whitman
  5570.           P.O. Box 1157
  5571.           North Wales, PA 19454
  5572.  
  5573.           (215) 641-7522 (days)
  5574.           (215) 234-4084 (evenings)
  5575.  
  5576.  
  5577.  
  5578.  
  5579.  
  5580.  
  5581.  
  5582.  
  5583.  
  5584.  
  5585.  
  5586.  
  5587.  
  5588.  
  5589.  
  5590.  
  5591.  
  5592.  
  5593.  
  5594.  
  5595.  
  5596.  
  5597.  
  5598.  
  5599.  
  5600.  
  5601.  
  5602.  
  5603.  
  5604.  
  5605.  
  5606.  
  5607.  
  5608.  
  5609.  
  5610.  
  5611.                                                                    83
  5612.  
  5613.     Appendix A: 8088 Mnemonic List
  5614.  
  5615.     This appendix lists the mnemonics which CHASM will recognize,
  5616.     grouped roughly by function.  Consult "The 8086 Book" for
  5617.     definitions of these instructions, and for the operands each will
  5618.     accept.  Mnemonics marked with an asterisk (*) will accept a 'B'
  5619.     or 'W' suffix for ambiguous memory references.
  5620.  
  5621.     Arithmetic:
  5622.  
  5623.     AAA      AAD       AAM       AAS       ADC*      ADD*      CBW
  5624.     CWD      CMP*      CMPS*     DAA       DAS       DEC*      DIV*
  5625.     IDIV*    IMUL*     INC*      MUL*      NEG*      SBB*      SUB* 
  5626.  
  5627.     Data Movement:
  5628.  
  5629.     LAHF     LDS       LEA       LES       LODS*     MOV*     MOVS*
  5630.     POP      POPF      PUSH      PUSHF     SAHF      XCHG     XLAT
  5631.  
  5632.     Logical:
  5633.  
  5634.     AND*     NOT*      OR*       TEST*     XOR* 
  5635.  
  5636.     String Primitives:
  5637.  
  5638.     CMPS*    LODS*     MOVS*     SCAS*     STOS*
  5639.  
  5640.     Instruction Prefixes:
  5641.  
  5642.     LOCK     REP       REPE      REPNE     REPNZ     REPZ      SEG
  5643.  
  5644.     Program Counter Control: (unconditional)
  5645.  
  5646.     CALL     CALLN     CALLF     JMP       JMPF      JMPN      JMPS
  5647.     RET
  5648.  
  5649.     Program Counter Control: (conditional)
  5650.  
  5651.     JA       JAE      JB      JBE      JC        JCXZ       JE
  5652.     JG       JGE      JL      JLE      JNA       JNAE       JNB
  5653.     JNBE     JNC      JNE     JNG      JNGE      JNL        JNLE
  5654.     JNO      JNO      JNP     JNS      JNZ       JO         JP
  5655.     JPE      JPO      JS      JZ       LOOP      LOOPE      LOOPNE
  5656.     LOOPNZ   LOOPZ
  5657.  
  5658.  
  5659.  
  5660.  
  5661.  
  5662.  
  5663.  
  5664.  
  5665.  
  5666.  
  5667.  
  5668.  
  5669.  
  5670.  
  5671.  
  5672.  
  5673.  
  5674.  
  5675.  
  5676.  
  5677.                                                                    84
  5678.  
  5679.     Processor Control:
  5680.  
  5681.     CLC      CLD       CLI       CMC       HLT       NOP       STC
  5682.     STD      STI       WAIT
  5683.  
  5684.     I/O:
  5685.  
  5686.     IN       OUT
  5687.  
  5688.     Interrupt:
  5689.  
  5690.     INT      INTO      IRET
  5691.  
  5692.     Rotate and Shift:
  5693.  
  5694.     RCL*     RCR*      ROL*      ROR*      SAL*      SAR*      SHL*
  5695.     SHR*
  5696.  
  5697.  
  5698.  
  5699.  
  5700.  
  5701.  
  5702.  
  5703.  
  5704.  
  5705.  
  5706.  
  5707.  
  5708.  
  5709.  
  5710.  
  5711.  
  5712.  
  5713.  
  5714.  
  5715.  
  5716.  
  5717.  
  5718.  
  5719.  
  5720.  
  5721.  
  5722.  
  5723.  
  5724.  
  5725.  
  5726.  
  5727.  
  5728.  
  5729.  
  5730.  
  5731.  
  5732.  
  5733.  
  5734.  
  5735.  
  5736.  
  5737.  
  5738.  
  5739.  
  5740.  
  5741.  
  5742.  
  5743.                                                                    85
  5744.  
  5745.     Appendix B: 8087 Mnemonic List
  5746.  
  5747.     ===> Advanced version only.
  5748.  
  5749.     This appendix lists the 8087 mnemonics recognized by CHASM's
  5750.     Advanced version, grouped roughly by function.
  5751.  
  5752.     Arithmetic:
  5753.  
  5754.     FADD     FADDP    FCHS     FDIV     FDIVP     FDIVR    FDIVRP
  5755.     FIADD    FIDIV    FIDIVR   FIMUL    FISUB     FISUBR   FMUL
  5756.     FMULP    FPREM    FSUB     FSUBP    FSUBR     FSUBRP    
  5757.  
  5758.     Mathematical Functions:
  5759.  
  5760.     F2XM1    FABS     FPATAN   FPTAN    FRNDINT   FSCALE   FSQRT
  5761.     FXTRACT  FYL2X    FYL2XP1
  5762.  
  5763.     Data Movement:
  5764.  
  5765.     FBLD     FBSTP    FILD     FIST     FISTP     FLD      FLD1
  5766.     FLDL2E   FLDL2T   FLDLG2   FLDLN2   FLDPI     FLDZ     FST
  5767.     FSTP     FXCH
  5768.  
  5769.     Comparison:
  5770.  
  5771.     FCOM     FCOMP    FCOMPP   FICOM    FICOMP    FTST      FXAM
  5772.  
  5773.     Processor Control:
  5774.  
  5775.     FCLEX    FDECSTP  FDISI    FENI     FFREE     FINCSTP   FINIT
  5776.     FNCLEX   FNDISI   FNENI    FNINIT   FNOP      WAIT      
  5777.  
  5778.     Processor Status:
  5779.  
  5780.     FLDCW    FLDENV   FNSAVE   FNSTCW   FNSTENV   FNSTSW    FRSTOR
  5781.     FSAVE    FSTCW    FSTENV   FSTSW
  5782.  
  5783.  
  5784.  
  5785.  
  5786.  
  5787.  
  5788.  
  5789.  
  5790.  
  5791.  
  5792.  
  5793.  
  5794.  
  5795.  
  5796.  
  5797.  
  5798.  
  5799.  
  5800.  
  5801.  
  5802.  
  5803.  
  5804.  
  5805.  
  5806.  
  5807.  
  5808.  
  5809.                                                                    86
  5810.  
  5811.     Appendix C: Differences Between CHASM and That Other Assembler
  5812.  
  5813.     Virtually all magazine articles about assembly language
  5814.     programming on the IBM PC assume that the reader is using That
  5815.     Other Assembler - you know, the outrageously priced one.  This
  5816.     appendix will try to summarize the differences between the two
  5817.     programs.  Please note that I do not own a copy of That Other
  5818.     Assembler, and therefore this section is not complete, nor even
  5819.     guaranteed to be correct.  I continue to work on this section,
  5820.     and anyone with more experience is invited to make additions or
  5821.     corrections, so this section will continually improve with time.
  5822.  
  5823.     A. General Differences
  5824.  
  5825.     The biggest difference is philosophical.  The IBM assembler was
  5826.     designed for use by professional assembly language programmers,
  5827.     to write operating systems and other huge projects.  This is
  5828.     reflected in the large size and relative complexity of the macro
  5829.     assembler.
  5830.  
  5831.     On the other hand, CHASM was designed for use by beginners, to
  5832.     write relatively short programs.  This was done by leaving out
  5833.     some of the power offered by IBM's assembler, in exchange for
  5834.     simplicity and ease of use.  The main simplification involved
  5835.     producing object code in the COM format, rather than the EXE
  5836.     format chosen by IBM. There are two main consequences of this
  5837.     choice:
  5838.  
  5839.        1. You can't link routines assembled by CHASM to
  5840.           Microsoft languages. (Although you *can* include them in
  5841.           Turbo Pascal or BASIC programs.)
  5842.  
  5843.        2. Your program has to fit in one 64K segment.  If (shudder!)
  5844.           you want to write a 256K assembly language program, you're
  5845.           out of luck.
  5846.  
  5847.     Like Pascal, the IBM assembler is a strongly typed language.  By
  5848.     requiring you to specify the *type* of each memory location you
  5849.     will access in your program, the IBM assembler generally knows
  5850.     what size of memory operand you want.  If you don't like the
  5851.     declared size, you have to override the default with the PTR
  5852.     operator.  Thus, to loading the AL register from a location
  5853.     declared word is a syntax error, unless you specify BYTE PTR
  5854.     before the address.
  5855.  
  5856.  
  5857.  
  5858.  
  5859.  
  5860.  
  5861.  
  5862.  
  5863.  
  5864.  
  5865.  
  5866.  
  5867.  
  5868.  
  5869.  
  5870.  
  5871.  
  5872.  
  5873.  
  5874.  
  5875.                                                                    87
  5876.  
  5877.     In analogy to the C language, CHASM is weakly typed. CHASM is
  5878.     perfectly happy extracting a byte from where you originally set
  5879.     aside a word - CHASM can't tell the difference. In most cases,
  5880.     CHASM can tell what size you want from context:  for example, if
  5881.     you're using a word register, it *must* be a word memory access. On
  5882.     the other hand, for any access to memory which doesn't have a
  5883.     register as the other operand, you must add either a 'B' or a 'W'
  5884.     to the instruction mnemonic used by IBM.
  5885.  
  5886.     B. Miscellaneous Differences:
  5887.  
  5888.        1. Short Jumps:
  5889.  
  5890.           IBM uses the SHORT keyword, CHASM uses an 'S' suffix.
  5891.           Example:
  5892.  
  5893.           JMP   SHORT label    ;ibm
  5894.           JMPS  label          ;chasm
  5895.  
  5896.        2. Offset Function:
  5897.  
  5898.           Where IBM precedes an operand with the keyword OFFSET,
  5899.           CHASM has a *function* called OFFSET. CHASM requires
  5900.           parentheses around the operand. Example:
  5901.  
  5902.           MOV   AX, OFFSET FCB  ;ibm
  5903.           MOV   AX, OFFSET(FCB) ;chasm
  5904.  
  5905.        3. Declaring Storage:
  5906.  
  5907.           A.  If you don't care what value a memory location is
  5908.               initialized to, the IBM assembler allows you to specify
  5909.               '?' as its contents.  In CHASM, if you don't care what
  5910.               value the variable is initialized to, just put down a
  5911.               zero.  Example:
  5912.  
  5913.                  DB   ?      ;ibm
  5914.                  DB   0      ;chasm
  5915.  
  5916.  
  5917.  
  5918.  
  5919.  
  5920.  
  5921.  
  5922.  
  5923.  
  5924.  
  5925.  
  5926.  
  5927.  
  5928.  
  5929.  
  5930.  
  5931.  
  5932.  
  5933.  
  5934.  
  5935.  
  5936.  
  5937.  
  5938.  
  5939.  
  5940.  
  5941.                                                                    88
  5942.  
  5943.           B.  The IBM assembler allows the keyword DUP as an operand
  5944.               in storage declaring pseudo-ops.  This means to repeat
  5945.               the definition as many times as the number just before
  5946.               the DUP.  Example:
  5947.  
  5948.               DW   3 DUP(?)  ;ibm
  5949.               DW   0, 0, 0   ;chasm
  5950.  
  5951.     4. ASSUME Pseudo-op:
  5952.  
  5953.        IBM's ASSUME pseudo-op tells the assembler where the segment
  5954.        registers will be pointing.  CHASM always assumes that the CS,
  5955.        DS and SS registers point to the beginning of the code
  5956.        segment, and that the SS register has been set up to point to
  5957.        a valid stack area.  If you find an ASSUME pseudo-op with
  5958.        different assumptions for the CS, DS and ES registers you'll
  5959.        have to figure out the addresses for memory references in the DS
  5960.        and ES segments yourself.
  5961.  
  5962.     5. Segment Pseudo-op:
  5963.  
  5964.        This pseudo-op is used to set up multiple segments in the IBM
  5965.        assembler.  Since CHASM only allows one segment, there is no
  5966.        equivalent pseudo-op.  If there is only one segment definition
  5967.        in an IBM assembler program, everything is fine, just leave
  5968.        the pseudo-op out for CHASM.
  5969.  
  5970.        Often times the SEGMENT pseudo-op is used to provide
  5971.        addressing of an area in the BIOS, or perhaps the interrupt
  5972.        vector table at the beginning of memory.  For example, if a
  5973.        program needed to get at the BIOS data area, in the IBM
  5974.        assembler you would define a dummy segment with the same
  5975.        structure as that in the BIOS listing in Technical Reference:
  5976.  
  5977.          DATA          SEGMENT AT 40H
  5978.          RS232_BASE    DW    4 DUP(?)
  5979.          PRINTER_BASE  DW    4 DUP(?)
  5980.          EQUIP_FLAG    DW    ?
  5981.          MFG_TST       DB    ?
  5982.          MEMORY_SIZE   DW    ?
  5983.          IO_RAM_SIZE   DW    ?
  5984.  
  5985.        All this is really accomplishing is giving a name to some
  5986.        memory locations which are outside the actual program being
  5987.        written.
  5988.  
  5989.  
  5990.  
  5991.  
  5992.  
  5993.  
  5994.  
  5995.  
  5996.  
  5997.  
  5998.  
  5999.  
  6000.  
  6001.  
  6002.  
  6003.  
  6004.  
  6005.  
  6006.  
  6007.                                                                    89
  6008.  
  6009.        In CHASM, you can simulate the dummy segment using a
  6010.        structure.  This will generate a series of immediate operands
  6011.        whose values correspond to the offsets of the labels in the
  6012.        dummy segment.  You can then reference the locations by
  6013.        enclosing the label names in square brackets, to coerce from
  6014.        type immediate to type address.
  6015.  
  6016.          DUMMY         STRUC            ;simulate dummy segment
  6017.          RS232_BASE    DW    0, 0, 0, 0
  6018.          PRINTER_BASE  DW    0, 0, 0, 0
  6019.          EQUIP_FLAG    DW    0
  6020.          MFG_TST       DB    0
  6021.          MEMORY_SIZE   DW    0
  6022.          IO_RAM_SIZE   DW    0
  6023.                        ENDSTRUC
  6024.                        MOV AX, [EQUIP_FLAG]
  6025.  
  6026.     6. Labels:
  6027.  
  6028.        The macro assembler indicates a local label by appending a
  6029.        colon (:).  The colon does not become part of the label, and
  6030.        is not included when referencing the label.  CHASM's labels
  6031.        are all global, and although they may end with a colon, the
  6032.        colon will become part of the label itself, and must then be
  6033.        used when referencing the label.  Example:
  6034.  
  6035.        a2:   mov ax,cx      ;ibm
  6036.              jmp a2         ; "
  6037.  
  6038.        a2:   mov ax,cx      ;chasm
  6039.              jmp a2:        ;  "
  6040.  
  6041.        CHASM does provide support for local labels in macros.  See the
  6042.        discussion on internal labels in the macro section of this
  6043.        document.
  6044.  
  6045.     7. Entry Point:
  6046.  
  6047.        The macro assembler allows you to specify the point within
  6048.        your program where execution will begin.  A label is put
  6049.        on the entry point, then to indicate entry, the same label is
  6050.        placed on the "END" pseudo-op.  Since COM programs must always
  6051.        start at offset 100H, CHASM doesn't allow setting an entry
  6052.        point, or use the END pseudo-op.  
  6053.  
  6054.  
  6055.  
  6056.  
  6057.  
  6058.  
  6059.  
  6060.  
  6061.  
  6062.  
  6063.  
  6064.  
  6065.  
  6066.  
  6067.  
  6068.  
  6069.  
  6070.  
  6071.  
  6072.  
  6073.                                                                    90
  6074.  
  6075.     Appendix D: Description of Files
  6076.  
  6077.     Your CHASM distribution disk contains a number of files.  This
  6078.     appendix will give a brief statement of the purpose of each.
  6079.  
  6080.     FILE           DESCRIPTION
  6081.     ----------------------------------------------------------------
  6082.     CHASM.CFG       Sample configuration file, for IBM printer.
  6083.  
  6084.     CHASM.COM       The CHASM program (either subset or advanced)
  6085.  
  6086.     CHASMS.COM      This file may appear on the disk of advanced
  6087.                     version users.  It is the current subset version,
  6088.                     that can be shared with others.  Please rename it
  6089.                     CHASM.COM on their disk, to avoid confusion.
  6090.  
  6091.     CHASM.DOC       This document.
  6092.  
  6093.     EXAMPLE.ASM     Sample source file.
  6094.  
  6095.     COM2DATA.ASM    Source code for COM2DATA filter.
  6096.  
  6097.     COM2DATA.DOC    Documentation for COM2DATA.
  6098.  
  6099.     FREEWARE.DOC    References to other User Supported programs.
  6100.  
  6101.     PRIMER.DOC      Simple introduction to assembly language.
  6102.  
  6103.     Occasionally, various other sample source files for CHASM will be
  6104.     distributed.  These files will have extension ASM, and will be
  6105.     accompanied by a corresponding DOC file.
  6106.  
  6107.  
  6108.  
  6109.  
  6110.  
  6111.  
  6112.  
  6113.  
  6114.  
  6115.  
  6116.  
  6117.  
  6118.  
  6119.  
  6120.  
  6121.  
  6122.  
  6123.  
  6124.  
  6125.  
  6126.  
  6127.  
  6128.  
  6129.  
  6130.  
  6131.  
  6132.  
  6133.  
  6134.  
  6135.  
  6136.  
  6137.  
  6138.  
  6139.                                                                    91
  6140.  
  6141.     Appendix E: Bug Reporting Procedure
  6142.  
  6143.     Although each version of CHASM is tested extensively prior to
  6144.     release, any program of this magnitude is bound to contain a few
  6145.     bugs.  It is the intention of Whitman Software to correct any
  6146.     genuine problem which is reported.
  6147.  
  6148.     If you think you have found a bug in CHASM, please take the time
  6149.     to report it for correction.  Although any report is helpful,
  6150.     correction of the problem will be easiest if you provide the
  6151.     following:
  6152.  
  6153.        1. The version of CHASM you are using.  Your problem may have
  6154.           been fixed already!
  6155.  
  6156.        2. A brief description of what you believe the problem to be.
  6157.  
  6158.        3. A printed listing of a source file which manifests the
  6159.           problem.
  6160.  
  6161.           * DON'T send a 5,000 line program which has one
  6162.             manifestation of the bug!  Isolate the problem area, or
  6163.             write a short sample routine that demonstrates the bug.
  6164.  
  6165.     Unlike normal commercial software, where corrections are saved up
  6166.     for a major revision, bugs in CHASM are fixed as soon as reported,
  6167.     with a new version released almost immediately (which is why there
  6168.     are so many versions in CHASM's revision history).
  6169.  
  6170.                    =====> BONUS <======
  6171.  
  6172.     If you send a copy of your problem source file on disk, it will
  6173.     be returned with either a new, corrected version of CHASM, or
  6174.     with an explanation of what you were doing wrong to *think* you'd
  6175.     found a bug.
  6176.  
  6177.  
  6178.  
  6179.  
  6180.  
  6181.  
  6182.  
  6183.  
  6184.  
  6185.  
  6186.  
  6187.  
  6188.  
  6189.  
  6190.  
  6191.  
  6192.  
  6193.  
  6194.  
  6195.  
  6196.  
  6197.  
  6198.  
  6199.  
  6200.  
  6201.  
  6202.  
  6203.  
  6204.  
  6205.                                                                    92
  6206.  
  6207.     Appendix F: Using CHASM on "Compatible" Systems
  6208.  
  6209.     CHASM was written specifically for the IBM PC, but should
  6210.     function normally on true "compatibles".  This appendix is a new
  6211.     section to summarize compatibility data for various systems.
  6212.  
  6213.     Since CHASM version 4 is a totally new program, little
  6214.     compatibility data is currently available.  If you are using (or
  6215.     are unable to use...) CHASM on a non-IBM computer, please write
  6216.     with your experiences.  Does CHASM work correctly on your system?
  6217.     Are there specific problem areas?  Can they be worked around?
  6218.  
  6219.     If you are using a non-IBM system, I strongly recommend that at
  6220.     least to start out, you include the line:
  6221.  
  6222.           /VIDEO 2
  6223.  
  6224.     in your CHASM.CFG file (see the section on "Modifying CHASM's I/O
  6225.     Defaults" for a discussion of the CHASM.CFG file).  This will
  6226.     force CHASM to use BIOS calls to access your video screen.  By
  6227.     default, CHASM writes directly to the screen hardware for maximum
  6228.     speed.  Without this line, if your hardware is not *strictly* IBM
  6229.     compatible, CHASM's output could be invisible, or your system
  6230.     could even hang up and require re-booting.
  6231.  
  6232.     The following systems are reported to run CHASM version 4
  6233.     successfully:
  6234.  
  6235.            AT&T 6300
  6236.            Chameleon
  6237.            Columbia 1600-1
  6238.            Compaq, Compaq DeskPro, Compaq Plus
  6239.            Corona PC-2
  6240.            Heath 151
  6241.            IBM PC, XT, AT, 3270 PC, 3270 PC/G
  6242.            ITT XTRA
  6243.            Kaypro 16
  6244.            Leading Edge
  6245.            Mega XT
  6246.            PC Designs FD-1
  6247.            Sanyo 555
  6248.            Superior PC
  6249.            Tandy 1000, 2000
  6250.            Televideo 1605
  6251.            Zenith 150
  6252.  
  6253.  
  6254.  
  6255.  
  6256.  
  6257.  
  6258.  
  6259.  
  6260.  
  6261.  
  6262.  
  6263.  
  6264.  
  6265.  
  6266.  
  6267.  
  6268.  
  6269.  
  6270.  
  6271.                                                                    93
  6272.  
  6273.  
  6274.     The following systems have one or more problems:
  6275.  
  6276.     ================================================================
  6277.     Tandy 1200HD - CHASM crashes on some systems.  The problem seems
  6278.     to be related to the exact amount of free memory available on the
  6279.     system.  You can prevent the crash by slightly changing the
  6280.     amount of free memory, to either a higher or lower number.
  6281.     Probably the easiest way to do this is to change the number of
  6282.     disk buffers, or load an extra device driver such as ANSII.SYS.
  6283.     Call Whitman Software if you have trouble.
  6284.     ================================================================
  6285.     ================================================================
  6286.     IBM PCjr. - Several users report getting as far as the source file
  6287.     prompt, at which point the program crashes.  Several other users
  6288.     (invariably with more than 128K of memory) report that CHASM works
  6289.     fine.  The PCjr uses part of user memory for the screen buffer, and
  6290.     PCjr users probably need 192K to run CHASM.
  6291.     ================================================================
  6292.  
  6293.  
  6294.  
  6295.  
  6296.  
  6297.  
  6298.  
  6299.  
  6300.  
  6301.  
  6302.  
  6303.  
  6304.  
  6305.  
  6306.  
  6307.  
  6308.  
  6309.  
  6310.  
  6311.  
  6312.  
  6313.  
  6314.  
  6315.  
  6316.  
  6317.  
  6318.  
  6319.  
  6320.  
  6321.  
  6322.  
  6323.  
  6324.  
  6325.  
  6326.  
  6327.  
  6328.  
  6329.  
  6330.  
  6331.  
  6332.  
  6333.  
  6334.  
  6335.  
  6336.  
  6337.                                                                    94
  6338.  
  6339.           ********ADVANCED VERSION ORDER FORM********
  6340.  
  6341.     Please add me to the list of registered CHASM users, and send me
  6342.     an upgrade to Advanced CHASM.  I understand that CHASM is
  6343.     copyrighted, and agree not to distribute any unauthorized copies
  6344.     of this Advanced version.
  6345.  
  6346.     Note that version 4 requires DOS 2 (or later)
  6347.     and 128K of memory. (192K for PCjr)
  6348.  
  6349.     Computer Model: ____________________________________
  6350.  
  6351.     Diskette format:            Total Memory: _______K
  6352.  
  6353.        __ single sided/9 sector
  6354.  
  6355.        __ doubled sided/9 sector
  6356.  
  6357.     Check one:
  6358.  
  6359.            ___ I enclose a check for $40
  6360.  
  6361.            ___ I am a past customer.  The enclosed check brings my
  6362.                total payment up to $40.
  6363.  
  6364.  
  6365.     Where did you hear about CHASM? ________________________________
  6366.  
  6367.     Name:    _______________________________________________________
  6368.  
  6369.     Address: _______________________________________________________
  6370.  
  6371.     City, State, Zip: ______________________________________________
  6372.  
  6373.  
  6374.     ================================================================
  6375.          Send order form and check to:
  6376.  
  6377.               Whitman Software
  6378.               P.O. Box 1157
  6379.               North Wales, PA 19454
  6380.  
  6381.  
  6382.  
  6383.  
  6384.  
  6385.  
  6386.  
  6387.  
  6388.  
  6389.  
  6390.  
  6391.  
  6392.  
  6393.  
  6394.  
  6395.  
  6396.  
  6397.  
  6398.  
  6399.  
  6400.  
  6401.  
  6402.  
  6403.                                                                    95
  6404.  
  6405.       ==============PRINTER ENHANCEMENT===================
  6406.  
  6407.  
  6408.     Michael Hoyt, of Soft and Friendly Software, has produced a set
  6409.     of printer enhancement programs using CHASM, which is sold under
  6410.     the name Prowriter Utilities.  The package supports the following
  6411.     printers:
  6412.  
  6413.         NEC 8023A-C
  6414.         Prowriter I  (C. Itoh 8510)
  6415.         Prowriter II (C. Itoh 1550)
  6416.  
  6417.     The package contains three programs:
  6418.  
  6419.         PRINT_CHARACTERS
  6420.         PRINT_SCREEN
  6421.         PRINT_SET
  6422.  
  6423.     Once PRINT_CHARACTERS is run, it attaches itself to DOS, and
  6424.     makes your printer have exactly the same character set as your
  6425.     video monitor.  The conversion is very professionally done.
  6426.     Particularly impressive are the line drawing characters, which
  6427.     actually form connected lines, both horizontally and vertically.
  6428.  
  6429.     As if this wasn't enough, PRINT_CHARACTERS adds italics
  6430.     capability as well.  The italics make very effective emphasis in
  6431.     documents and letters, and look really good.
  6432.  
  6433.     PRINT_SCREEN is a graphics screen dump, activated by the normal
  6434.     Shift/PrtSc sequence.  Several options are available which trade
  6435.     off speed and print quality.  Since I have the mono card, I
  6436.     haven't tried PRINT_SCREEN, but Michael sent me a sample printout
  6437.     which looked quite nice.
  6438.  
  6439.     PRINT_SET is a menu-driven program to turn on and off the various
  6440.     special printing modes supported by these printers.  A simple but
  6441.     effective program.
  6442.  
  6443.     I've been using this package with my NEC 8023 for a few months
  6444.     now, and I like them quite a bit.  To get a copy, send $35 to:
  6445.  
  6446.         Soft and Friendly
  6447.         RR 2 Box 65
  6448.         Solsberry, IN 47459
  6449.  
  6450.  
  6451.  
  6452.  
  6453.  
  6454.  
  6455.  
  6456.  
  6457.  
  6458.  
  6459.  
  6460.  
  6461.  
  6462.  
  6463.  
  6464.  
  6465.  
  6466.  
  6467.  
  6468.  
  6469.                                                                    96
  6470.  
  6471.  
  6472.  
  6473.          ================= NEW PRODUCT ==================
  6474.  
  6475.     If you use the IBM/Microsoft BASIC compiler, chances are your
  6476.     programs are bigger and slower than they have to be.  If all
  6477.     unreferenced line numbers are removed from your source program,
  6478.     and the /N switch is used, BASCOM will "optimize" your program.
  6479.     The result is tighter, more efficient code.
  6480.  
  6481.     NUMZAP is a utility which carefully scans your source file, and
  6482.     deletes all the non-essential line numbers.  Performing this task
  6483.     by hand would be prohibitively time consuming and you'd probably
  6484.     introduce errors into your program in the process.  NUMZAP will
  6485.     do the job in minutes, 100% error free.
  6486.  
  6487.     The old BASIC version of CHASM was passed through NUMZAP, and the
  6488.     resulting compiled code shrank by a factor of 10% (!).  That 10%
  6489.     reduction could make the difference between your program running
  6490.     in 64K, or having users with minimal systems get "Out of Memory"
  6491.     messages just before your program crashes.
  6492.  
  6493.     An added advantage to using NUMZAP is that bigger programs can be
  6494.     compiled.  You may not be aware that there is a limit on the size
  6495.     of program which the compiler can handle.  BASCOM uses up space
  6496.     remembering the offset of each line number in your program. If
  6497.     you have too many numbered lines, BASCOM will run out of room and
  6498.     you'll get a unending series of "TC" (Too Complex) error
  6499.     messages.  By eliminating the unneeded line numbers, you give
  6500.     BASCOM more elbow room.  The free space available to compile
  6501.     CHASM increased 27% (!) after using NUMZAP.
  6502.  
  6503.     NUMZAP is available under the standard FREEWARE deal - just send
  6504.     a formatted disk and self-addressed, stamped return mailer to:
  6505.  
  6506.                 David Whitman
  6507.                 P.O. Box 1157
  6508.                 North Wales, PA 19454
  6509.  
  6510.     Be sure to specify that you are interested in NUMZAP.  If you
  6511.     like the program, a donation of $15 is suggested.
  6512.  
  6513.  
  6514.  
  6515.  
  6516.  
  6517.  
  6518.  
  6519.  
  6520.  
  6521.  
  6522.  
  6523.  
  6524.  
  6525.  
  6526.  
  6527.  
  6528.  
  6529.  
  6530.  
  6531.  
  6532.  
  6533.  
  6534.  
  6535.